Я немного проиллюстрирую разницу:
Вот что в основном происходит, когда вы пишете new Animal()
:
//creating a new object
var res = {};
//setting the internal [[prototype]] property to the prototype of Animal
if (typeof Animal.prototype === "object" && Animal.prototype !== null) {
res.__proto__ = Animal.prototype;
}
//calling Animal with the new created object as this
var ret = Animal.apply(res, arguments);
//returning the result of the Animal call if it is an object
if (typeof ret === "object" && ret !== null) {
return ret;
}
//otherise return the new created object
return res;
И вот что в принципе происходит с Object.create
:
//creating a new object
var res = {};
//setting the internal [[prototype]] property to the prototype of Animal
if (typeof Animal.prototype !== "object") {
throw "....";
}
res.__proto__ = Animal.prototype;
//return the new created object
return res;
Таким образом, он делает то же самое, но не вызывает функцию Animal
, а также всегда возвращает новый созданный объект. В вашем случае вы получаете два разных объекта. С помощью первого метода вы получите:
Dog.prototype = {
name: undefined,
__proto__: Animal.prototype
};
и со вторым методом:
Dog.prototype = {
__proto__: Animal.prototype
};
Вам действительно не нужно иметь свойство name
в вашем прототип, потому что вы уже назначили его вашему экземпляру Dog
с помощью Animal.call(this, 'Dog');
.
Ваша основная цель - предоставить вашему экземпляру Dog
доступ ко всем свойствам прототипа Animal
, который достигается с помощью обоих методов. Первый способ, однако, делает некоторые дополнительные вещи, которые на самом деле не нужны в вашем случае, или даже могут вызывать нежелательные результаты, о которых упоминал Pumbaa80.