...处理具有不同属性但相同方法的多个对象的常用方法是使用构造函数...
是的,另一种常见的方式是(如您所见)Object.create。
我的理解是goat继承/引用Animal.
不完全的。在new Animal表达式中,goat将被分配的对象Animal.prototype作为其底层原型。与 没有直接联系Animal,只是与Animal.prototype。(在正常情况下,通过其属性Animal.prototype有一个引用,尽管如果有人将新对象分配给该链接可能会被破坏。)AnimalconstructorAnimal.prototype
继承在Animal这里丢失了,还是Goat仍在引用Animal方法?
在您的非构造函数示例中,goatgetsAnimal作为其底层原型,因此对于goat自身未找到的任何属性,JavaScript 引擎将查看Animal它是否具有它。在您的示例中,这意味着goat使用sayHellofrom Animal,但不是type,因为goat有自己的type。
大致相当于:
function Animal ( type ) {
this.type = type
};
Animal.prototype.sayHello = function () {
return 'Hi, I am a ' + this.type
};
var goat = new Animal( 'Goat' );
...Object.create用于设置原型,而不是如下所示:
var animalPrototype = {
sayHello: function () {
return 'Hi, I am a ' + this.type
}
};
function createAnimal(type) {
var rv = Object.create(animalPrototype);
rv.type = type;
return rv;
};
var goat = createAnimal( 'Goat' );
回复您的评论:
会不会有任何问题,包括animalPrototype里面createAnimal然后打电话Object.create(this.animalPrototype)?
如果你是这个意思:
function createAnimal(type) {
var animalPrototype = { // Issue #1
sayHello: function () {
return 'Hi, I am a ' + this.type
}
};
var rv = Object.create(this.animalPrototype); // Issue #2
rv.type = type;
return rv;
};
var goat = createAnimal( 'Goat' );
...那么是的,有两个问题:
- 你会为每次调用创建一个新 的,这违背了目的,并且 2.在调用中将是全局对象(松散模式)或(严格模式),所以可能不是你想要的表达式。
animalPrototypecreateAnimalthiscreateAnimalundefinedthis.animalPrototype
你可以这样做:
function createAnimal(type) {
var rv = Object.create(createAnimal.proto);
rv.type = type;
return rv;
};
createAnimal.proto = {
sayHello: function () {
return 'Hi, I am a ' + this.type
}
};
var goat = createAnimal( 'Goat' );
当然,这可能会让人们感到困惑,因为它看起来很像构造函数。