__proto__
/ setPrototypeOf
не совпадают с назначением прототипа объекта. Например, когда у вас есть функция / объект с назначенными ей членами:
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
Кажется, что все фокусируются только на прототипе и забывают, что функции могут иметь назначенные ему члены и создаваться после мутации , В настоящее время нет другого способа сделать это, не используя __proto__
/ setPrototypeOf
. Едва ли кто-либо использует конструктор без возможности наследования от родительской конструкторской функции, а Object.create
не может служить.
И плюс, это два вызова Object.create
, которые в настоящий момент являются нечестивыми медленными в V8 (оба браузера и Node), что делает __proto__
более жизнеспособным выбором