原型继承学习者的标准示例:
function Animal(name) {
this.name = name;
this.speed = 0;
}
Animal.prototype.stop = function() {
this.speed = 0;
};
Animal.prototype.run = function(speed) {
this.speed += speed;
};
function Rabbit(name) {
this.name = name;
this.speed = 0;
}
Rabbit.prototype = Object.create(Animal.prototype);
Rabbit.prototype.constructor = Rabbit;
Rabbit.prototype.jump = function() {
this.speed++;
};
var rabbit = new Rabbit('Bunny');
令我困惑的是:
Rabbit
的原型设置为Animal
。jump()
方法是在Rabbit
的原型上定义的 - 而不是Rabbit
本身。jump()
Rabbit
醇>
这似乎是合理的,因为我不希望jump()
成为Animal
的一部分,而是非逻辑的,因为我在jump()
的实例上定义了Animal
。
是否对prototype
属性中的对象有一些特殊处理,例如“设置对象,在原型中定义为__proto__
,但是将所有其他方法定义移动到子对象中”?或者我弄错了?
答案 0 :(得分:1)
回答你的问题:
1)Rabbit的原型设置为Animal:
您可以使用以下代码表明:
Rabbit.prototype = Object.create(Animal.prototype);
Object.create()
创建一个新对象,原型作为第一个参数
它用于创建Animal和Rabbit之间的原型链。
2)在Rabbit的原型上定义了jump()方法 - 而不是在Rabbit本身上。
之所以发生这种情况,是因为您将此方法完全添加到原型中,但Rabbit
实例上的不是。
Rabbit.prototype.jump = function() {
this.speed++;
};
3)Google Chrome将jump()显示为Rabbit的一部分。
是的,jump()
方法是Rabbit的一部分:继承自Rabbit.prototype。
4)这似乎是合理的,因为我不希望jump()成为Animal的一部分,但是非逻辑,因为我在Animal的实例上定义了jump()
你在Animal的一个实例上定义jump()
(一个新的实例,因为使用了Object.create(),但仍然保留了Animal原型),这将成为Rabbit的原型。
5)“设置对象,在原型中定义为 proto ,但将所有其他方法定义移动到子对象中”
当实例从原型对象继承属性和方法时,它会在运行时自动发生。
可能令人困惑的一件事是Google控制台显示的原因:__proto__: Rabbit
和__proto__: Animal
。实际上它显示了构造函数名称,它与原型对象链接。
答案 1 :(得分:-1)
你只是使用Rabbit的实例来获取原型 - 但是Animal有一个对同一原型的引用 - 实质上,Rabbit扩展了Animal(反之亦然)。因此,如果您更改Rabbit的原型,您也可以更改Animal的原型。
您可以定义兔子本身的跳跃,而不是原型。或者,您可以将Rabbit的原型设置为新的Animal对象并进行修改。