sof
sof

Reputation: 9649

Confusing "instanceof " result

    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

Why is the "instanceof" result not "false", because the "constructor" doesn't refer to itself but the inherited prototype?

Upvotes: 5

Views: 140

Answers (2)

Felix Kling
Felix Kling

Reputation: 816232

instanceof does not use the constructor property. It internally calls the [HasInstance] method of the function object, which is described in §15.3.5.3 of the specification.

It compares the prototype of the object (and the prototype of the prototype of the object, etc) with the prototype property of the function.

A similar implementation would be:

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;
}

As far as I know, the constructor property is not used by any internal methods, only by user generated code.

Upvotes: 6

Timmetje
Timmetje

Reputation: 7694

Bar.prototype = new Foo()

therefore

Bar.prototype instanceof Foo

therefore

Bar.prototype.contructor === Foo

Constructor returns a reference to the actual function

Instanceof

The difference between instanceof and the constructor property (apart from the obvious syntactic difference) is that instanceof inspects the object’s prototype chain.

So:

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

The above are all true.

Upvotes: 1

Related Questions