1

我创建了一个 Flash 对象 (HTMLObjectElement)(使用 jQuery)并将其添加到 DOM。这在所有浏览器中都可以正常工作。该对象保存/存储在名为“o.data.cam”的变量中。其他函数检查此变量是否有效。

例如:

if( typeof o.data.cam == "object")
 { do this }

这在除 Firefox 之外的所有浏览器中都可以正常工作。o.data.cam是一个函数而不是一个对象。我认为这是一种奇怪的行为,因为创建了对象,为什么将其报告为函数?

在 Firefox 17.0.1(最新)中,创建的 HTMLObjectElement(对象标记)在转储时返回 [object HTMLObjectElement]。我可以理解这一点(?),因为它可以与原生函数(受保护)相同,例如原生函数 => [原生函数]。否则有点奇怪,因为大多数 DOM 元素都可以检查,那为什么不是他的呢?

但与其他浏览器相比,有一些差异需要注意:

                        Firefox                       Chrome     MSIE      Opera
___________________________________________________________________________________________
dump o.data.cam             [object HTMLObjectElement]    Object*    Object*   Object*
typeof o.data.cam           "function"                   "Object"   "Object"  "Object"
typeof HTMLObjectElement    "object"                     "function" "Object"  "function"
  • (星号)= 打印对象树

注意: - 引号之间是一个字符串,一个“typeof”结果。

typeof 评估在所有浏览器中返回“对象”(Firefox 除外),我认为这是正确的,因为当它是一个函数并作为类(新函数)创建时,它必须报告为对象(我认为?)

我的问题是:这是一个错误还是我错过了什么?

编辑:创建此函数以检查它是否是有效的 DOM 元素。这样做安全吗?现在 Firefox 返回 true。

function isDOM(oo)
{ 
  if( oo )
  {
   if( typeof oo instanceof jQuery )
    { return !!oo[0]; }
   if( typeof oo == 'object' || typeof oo == 'function' )
    { return ( typeof oo.tagName == 'string' && oo.tagName.length > 0 ); }
  }
  return false; 
}
4

1 回答 1

1

根据 EcmaScript 规范,所有具有 [[Call]] 内部方法的对象都必须为 typeof 返回“函数”。

HTMLObjectElement 的实例可以有一个 [[Call]] 内部方法,因为插件可以使它们被实例化的对象可调用。

所以唯一的问题是如果插件不想被调用,对象是否应该始终是可调用的并抛出,或者它是否应该根据插件正在做的事情在“对象”和“函数”之间动态更改类型. 我猜还有第三种选择,即忽略规范并报告“对象”,即使有 [[Call]]。

Firefox 是前者:总是有一个 [[Call]],所以 typeof 报告“函数”。其他浏览器可能要么使 [[Call]] 动态出现和消失,要么完全违反规范。

于 2012-12-14T09:15:27.777 回答