Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusing "instanceof " result

Tags:

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

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

like image 862
sof Avatar asked Jun 13 '13 13:06

sof


2 Answers

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.

like image 114
Felix Kling Avatar answered Oct 30 '22 02:10

Felix Kling


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.

like image 22
Timmetje Avatar answered Oct 30 '22 02:10

Timmetje