From the MDN docs for the standard setPrototypeOf function as well as the non-standard __proto__ property:
Mutating the [[Prototype]] of an
__proto__
/setPrototypeOf
aren't the same as assigning to the object prototype. For example, when you have a function/object with members assigned to it:
function Constructor(){
if (!(this instanceof Constructor)){
return new Constructor();
}
}
Constructor.data = 1;
Constructor.staticMember = function(){
return this.data;
}
Constructor.prototype.instanceMember = function(){
return this.constructor.data;
}
Constructor.prototype.constructor = Constructor;
// By doing the following, you are almost doing the same as assigning to
// __proto__, but actually not the same :P
var newObj = Object.create(Constructor);// BUT newObj is now an object and not a
// function like !!!Constructor!!!
// (typeof newObj === 'object' !== typeof Constructor === 'function'), and you
// lost the ability to instantiate it, "new newObj" returns not a constructor,
// you have .prototype but can't use it.
newObj = Object.create(Constructor.prototype);
// now you have access to newObj.instanceMember
// but staticMember is not available. newObj instanceof Constructor is true
// we can use a function like the original constructor to retain
// functionality, like self invoking it newObj(), accessing static
// members, etc, which isn't possible with Object.create
var newObj = function(){
if (!(this instanceof newObj)){
return new newObj();
}
};
newObj.__proto__ = Constructor;
newObj.prototype.__proto__ = Constructor.prototype;
newObj.data = 2;
(new newObj()).instanceMember(); //2
newObj().instanceMember(); // 2
newObj.staticMember(); // 2
newObj() instanceof Constructor; // is true
Constructor.staticMember(); // 1
Everybody seem to be focusing only on the prototype, and forget that functions can have members assigned to it and instantiated after mutation. There's currently no other way of doing this without using __proto__
/setPrototypeOf
. Barely anyone use a constructor without the ability to inherit from a parent constructor function, and Object.create
fails to serve.
And plus, that's two Object.create
calls, which at the present moment, is ungodly slow in V8 (both browser and Node), which makes __proto__
a more viable choice