繁体   English   中英

Javascript:typeof和instanceof结果是否矛盾?

[英]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”返回“对象”。

objectembed 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"

objectembed HTML元素是具有内部[[Call]]属性的对象,因此typeof必须返回"function"

错误268945中对此进行了解释:

  • 评论#15 ,作者:Boris Zbarsky:

    [[Call]]在DOM端是非常有意的:这些是​​可调用的对象。

  • 评论#16 ,汤姆舒斯特:

    这个bug无效,这些对象有[[Call]]内部方法,ES5 11.4.3明确说“Object(native或_host_并且实现[[Call]])”=>“function”。

由于objectembed 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返回一个函数。 构造函数告诉您该函数“HT​​MLElement”的名称。

例如,您可以使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM