[英]Javascript: typeof and instanceof results contradicting?
在对象上执行typeof和instanceof时,我看到了相互矛盾的结果。
我有以下测试页面:
<html>
<body>
<object id="test" />
<script type="text/javascript">
var foo = document.getElementById("test");
console.log(typeof foo); // returns "function"
console.log(foo instanceof Function); // returns false
console.log(foo instanceof Object); // returns true
</script>
</body>
</html>
“typeof foo”返回“function”但“foo instanceof Function”返回false。
这对我来说没有意义。 对象如何将类型设为函数但不是函数的实例? 另外,我希望“typeof foo”返回“对象”。
object
和embed
HTML元素是宿主对象。
ECMAScript3 11.4.3没有定义应为这些返回的typeof
。 对象的返回值表是
- 对象(本机的,不实现[[Call]]):
"object"
- 对象(native和implements [[Call]]):
"function"
- 对象(主机):依赖于实现
但是,返回"function"
与ECMAScript5 11.4.3一致:
- 对象(本机的,不实现[[Call]]):
"object"
- 对象(本机或主机并实现[[Call]]):
"function"
- 对象(主机并没有实现[[Call]]):实现定义,但可能不是
"undefined"
,"boolean"
,"number"
或"string"
。
object
和embed
HTML元素是具有内部[[Call]]属性的对象,因此typeof
必须返回"function"
。
错误268945中对此进行了解释:
评论#15 ,作者:Boris Zbarsky:
[[Call]]在DOM端是非常有意的:这些是可调用的对象。
评论#16 ,汤姆舒斯特:
这个bug无效,这些对象有[[Call]]内部方法,ES5 11.4.3明确说“Object(native或_host_并且实现[[Call]])”=>“function”。
由于object
和embed
HTML元素实现了内部[[Call]]属性,因此它们是可调用对象 。 但是,它们不是功能:
4.3.24功能
Object类型的成员,它是标准内置
Function
构造Function
一个实例,可以作为子例程调用
object
HTML元素继承自HTMLObjectElement.prototype
,并embed
来自HTMLEmbedElement.prototype
HTML元素。
原型链继续
HTMLObjectElement.prototype
HTMLElement.prototype
Element.prototype
Node.prototype
Object.prototype
因此,它们不是Function
实例,因为它们不从Function.prototype
继承。
基本的事实是DOM元素(例如,使用document.getElementById()
)不是本机JavaScript对象。 相反,它们是主机对象 。 因此,它们不受适用于本机JavaScript对象的通常规则的约束,并且它们的行为将(非常合理地)从一个浏览器到下一个浏览器变化很大。
简而言之,所有的赌注都没有了。 不要依赖于其记录的API之外的宿主对象的行为。
相关参考:
Safari为typeof document.getElementsByTagName('p')返回' function ',
这让我很久以前的一段时间,当我假设所有客户都会返回“对象”时。
测试我们的前概念是很好的,即使异常没有发生。
此外,调试器很可爱,但它们并不总是报告与浏览器相同的值。
在第一个示例中,运行脚本时不存在此dom元素。 在你的第二个,它的答案是正确的,第二个是typeof和constructor之间的区别。 typeof返回一个函数,因为document.getElementById返回一个函数。 构造函数告诉您该函数“HTMLElement”的名称。
例如,您可以使用var myElement = new HTMLElement()开始创建自己的元素
我不确定为什么为<object>
节点返回'function',但是instaceof Function
失败的原因是因为它本质上是对构造函数的检查,其区别可以如此说明
<html>
<body>
<object id="test" />
<script type="text/javascript">
var foo = document.getElementById("test");
var bar = function() {}
console.log( typeof foo );
console.log( foo instanceof Function );
console.log( foo.constructor ); // Object()
console.log( typeof bar );
console.log( bar instanceof Function );
console.log( bar.constructor ); // Function()
</script>
</body>
</html>
所以在这种情况下,它实际上typeof
是奇怪的行为,而不是在一个方式是记录 ,我可以看到。
我发现了一些额外的奇怪行为。
如果您将javascript代码移动到对象上方,则typeof正常工作但instanceof不起作用。
<html>
<body>
<script type="text/javascript">
var foo = document.getElementById("test");
console.log(typeof foo); // returns object (this is correct now)
console.log(foo instanceof Function); // returns false (this is correct)
console.log(foo instanceof Object); // returns false (this is wrong)
console.log(foo instanceof HTMLElement); // returns false (this is wrong)
console.log(foo instanceof Node); // returns false (this is wrong)
</script>
<object id="test" />
</body>
VS
<html>
<body>
<object id="test" />
<script type="text/javascript">
var foo = document.getElementById("test");
console.log(typeof foo); // returns function (this is wrong)
console.log(foo instanceof Function); // returns false
console.log(foo instanceof Object); // returns true (this is correct)
console.log(foo instanceof HTMLElement); // returns true (this is correct)
console.log(foo instanceof Node); // returns true (this is correct)
</script>
</body>
所以基本上如果脚本在对象下面,typeof表现得很奇怪,但是如果脚本在对象instanceof之上,则表现得很奇怪。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.