wheresrhys
wheresrhys

Reputation: 23500

Why does adding a prototype lead to non-equality of constructors

Just when I think I understand js objects they throw something new at me.

In this code (fiddle: http://jsfiddle.net/x8Eng/1/)

var impl = function () {
        var P = function () {};
        P.prototype = {};
        return P;
    },
    P = impl();
    p = new P();

console.log(p.constructor === P);

checking for equality on the constructor returns false when I add a prototype, but if you remove the line that adds the prototype then it returns true. Extending the prototype via P.prototype.prop = 'prop' preserves equality too. p instanceof P always returns true.

Can someone please explain the intricacies of why this happens?

Upvotes: 1

Views: 76

Answers (3)

georg
georg

Reputation: 214949

Objects created in your code (via new or literals like {}) do not have a "constructor" property, therefore when you write p.construtor, it's resolved via the prototype chain, that is, p.__proto__ is looked for, then, p.__proto__.__proto__ etc.

Since you set P.prototype to an empty object, the first call fails (p.__proto__, aka P.prototype, aka {} has no constructor), so the engine looks in {}.__proto__, which is Object.prototype and finds constructor there. Of course, this one has nothing to do with P, it's just the default Object constructor.

Note that instanceof doesn't use constructors, x instanceof F is interpreted as x.__proto__ == F.prototype or x.__proto__.__proto__ == F.prototype etc

Upvotes: 2

mohkhan
mohkhan

Reputation: 12305

"Object" class is the prototype of every object in JS and constructor is a property of Object class. So if you reassign the prototype property of any object to something else, the constructor property which belongs to Object class is also lost. But if you add any new property to the prototype of an object, the constructor is not lost.

Upvotes: 0

Rob W
Rob W

Reputation: 348972

    P.prototype = {};

This does not only change the prototype, it also sets the constructor to Object. And Object is definitely not identical to P.

If you want that the equality holds, set the constructor property after re-assigning the prototype:

var P = function () {};
P.prototype = {};
P.prototype.constructor = P;
return P;

Upvotes: 2

Related Questions