当我使用 chrome devtools 时,我很惊讶。
但似乎 typeof <object>
是一个“函数”。
我还没有找到任何解释或引用资料。
这是一个简单的例子:https://jsfiddle.net/fez34zbf/
HTML:
<object></object>
<video></video>
JS:
console.log(typeof document.querySelector('object'));
console.log(typeof document.querySelector('video'));
控制台结果将是:
function
object
有什么想法吗?
最佳答案
如前所述,对于所有具有[[Call]]
内部方法的对象,typeof 必须返回"function"
。( spec )。所以有趣的部分是 HTMLObjectElement
的实例出于某种原因有一个 [[Call]]
内部方法。
关于 firefox 的错误报告以及chrome .虽然没有关于 Chrome 问题的 firefox 问题的回复,但有一个解释,其中 [[Call]]
被添加到 HTMLObjectElement
Yes, that's correct. SetCallAsFunctionHandler() makes the object callable according to EcmaScript, hence we have to return "function" for typeof.
SetCallAsFunctionHandler
似乎是 v8 中的一些实现细节。根据问题,chrome 曾经将 object
报告为 HTMLObjectElement
的 typeof
实例,但他们将其更改为与 firefox 兼容。
现在为什么 HTMLObjectElement
上有一个 [[Call]]
内部方法?作为this stackoverflow answer暗示这似乎被某些插件使用。 HTMLObjectElement
由插件(例如 flash)使用。其中一些插件可能除了使用此功能的输入。
查看 source code在 Chromium 中,似乎有一些代码确实可以处理一些遗留回调(V8HTMLEmbedElement.cpp
和 V8HTMLPlugInElementCustom.cpp
)。
也在 this 中firefox ticket 这已确认
why on earth are Embed/Object elements callable in the first place? [...] As far as anyone can tell, because some plug-ins do something when you call them and no one wants to break that for compat reasons...
我没有找到任何定义此行为的规范。 html5 规范提到了 legacy caller operation但没有明确定义它是如何工作的
总结一下:typeof document.createElement('object')
是 “function”
因为它有一个 [[Call]]
内部方法。由于遗留原因,它有一个 [[Call]]
内部方法。
如果你在chrome中执行这段代码
(function(){
'use strict';
return document.createElement('object')()
})()
你得到 undefined
作为返回值。如果你在 firefox 中执行它,你会得到一个异常
Component is not available" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: debugger eval code :: :: line 1" data: no
有趣的是 document.createElement('object') instanceof Function
是 false
因此 Function.prototype
中的方法都不存在HTMLObjectElement
.
关于javascript - 为什么 <object> 的类型是一个函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37657356/