在对象上执行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”正在返回“功能”但是 “foo instanceof Function”返回false。
这对我没有意义。对象如何将类型设为函数但不是函数的实例?另外,我希望“typeof foo”返回“object”。
答案 0 :(得分:2)
重要的事实是DOM元素(例如,使用document.getElementById()
获得)不是本机JavaScript对象。相反,它们是主机对象。因此,它们不受适用于本机JavaScript对象的通常规则的约束,并且它们的行为将(非常合理地)从一个浏览器到下一个浏览器变化很大。
简而言之,所有赌注都已关闭。不要依赖于其记录的API之外的宿主对象的行为。
相关参考资料:
答案 1 :(得分:1)
Safari为 typeof document.getElementsByTagName('p')返回'功能',
这给了我一段时间以前的糟糕时间,当时我假设所有客户都会返回'对象'。
测试我们的前概念是好的,即使异常没有发生也是如此。
此外,调试器很可爱,但它们并不总是报告与浏览器相同的值。
答案 2 :(得分:1)
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"
。
Bug 268945中解释了这一点:
Comment #15,作者:Boris Zbarsky:
[[Call]]在DOM方面是非常有意的:这些是可调用的对象。
Comment #16,汤姆舒斯特:
这个bug无效,这些对象有[[Call]]内部方法和 ES5 11.4.3明确地说“对象(本机或_host_并且确实实现 [[Call]])“=&gt;”function“。
由于object
和embed
HTML元素实现了内部[[Call]]属性,因此它们是可调用对象。但是,它们不是功能:
4.3.24功能
Object类型的成员,它是标准内置的实例
Function
构造函数,可以作为子例程调用
object
HTML元素继承自HTMLObjectElement.prototype
的{{1}}和embed
HTML元素。
原型链继续
HTMLEmbedElement.prototype
HTMLObjectElement.prototype
HTMLElement.prototype
Element.prototype
Node.prototype
因此,它们不是Object.prototype
个实例,因为它们不会从Function
继承。
答案 3 :(得分:0)
我不确定为什么'{1}}节点返回'function',但<object>
失败的原因是因为它基本上是对构造函数的检查,其区别可以说明如下所以
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>
表现得很奇怪,而不是我能看到is documented的方式。
答案 4 :(得分:0)
在第一个示例中,运行脚本时此dom元素不存在。 在你的第二个,它的答案是正确的,第二个是typeof和constructor之间的区别。 typeof返回一个函数,因为document.getElementById返回一个函数。 构造函数告诉您该函数的名称“HTMLElement”。
例如,你可以用var myElement = new HTMLElement()
开发自己的元素答案 5 :(得分:-1)
我发现了一些额外的奇怪行为。
如果你将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之上,则表现得很奇怪。