混淆“instanceof”结果

时间:2013-06-13 13:13:29

标签: javascript

    function Foo() {}

    function Bar() {}

    Bar.prototype = new Foo()

    console.log("Bar.prototype.constructor === Foo ? " 
     + (Bar.prototype.constructor === Foo))

    console.log("new Bar() instanceof Bar? " 
     + (new Bar() instanceof Bar))
=> Bar.prototype.constructor === Foo ? true
=> new Bar() instanceof Bar? true

为什么" instanceof"结果不是" false",因为"构造函数"并没有引用自己,而是继承原型?

2 个答案:

答案 0 :(得分:6)

instanceof不使用constructor属性。它在内部调用函数对象的[HasInstance]方法,该方法在§15.3.5.3 of the specification

中描述

它将对象的原型(以及对象原型的原型等)与函数的prototype属性进行比较。

类似的实现方式是:

function myInstanceOf(obj, Constr) {
    // get prototype of object
    var proto = Object.getPrototypeOf(obj);

    // climb up the prototype chain as long as we don't have a match
    while (proto !==  Constr.prototype && proto !== null) {
        proto = Object.getPrototypeOf(proto);
    }

    return proto === Constr.prototype;
}

据我所知,constructor属性不被任何内部方法使用,只能由用户生成的代码使用。

答案 1 :(得分:1)

Bar.prototype = new Foo()

因此

Bar.prototype instanceof Foo

因此

Bar.prototype.contructor === Foo

构造函数返回对实际函数的引用

<强> INSTANCEOF

instanceof和构造函数属性之间的区别(除了明显的语法差异)是instanceof检查对象的原型链。

所以:

=> new Bar() instanceof Foo? true
=> new Bar() instanceof Bar? true
=> new Bar() instanceof Object? true

以上都是真的。