我可以创建一个Cat
对象并在其原型上设置一个方法来打印出猫的名字。
var log = function(message) {
var results = $('#result');
results.append('<p>' + message + '</p>');
};
function Cat(name) {
this.name = name;
}
Cat.prototype.speak = function() {
log('My name is ' + this.name);
};
var fluffy = new Cat('Fluffy');
var tiddles = new Cat('Tiddles');
log(fluffy.name);
fluffy.speak();
log(tiddles.name);
tiddles.speak();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"></div>
但是,当我尝试将猫的原型设置为动物时,我无法访问speak
方法:
function Animal(name, sound) {
this.name = name;
this.sound = sound;
this.speak = function() {
log(sound + '! My name is ' + name);
};
}
function Cat(name) {
this.prototype = new Animal(name, 'Meow');
}
var fluffy = new Cat('Fluffy');
fluffy.speak(); // TypeError: undefined is not a function
为什么fluffy
没有得到原型的speak()
方法?
答案 0 :(得分:7)
如果你想学习如何在JS中进行继承,please read this guide。 prototype
是构造函数的属性,而不是实例。
为什么
fluffy
没有得到原型的speak()
方法?
因为它不在原型上。你永远不会改变Cat.prototype
。您设置Animal
的方式,您必须在Animal
内调用Cat
:
function Cat(name) {
Animal.call(this, name, 'Meow');
}
但是如果你想要正确的原型继承,请在speak
上定义Animal.prototype
并通过Object.create
设置继承:
function Animal(name, sound) {
this.name = name;
this.sound = sound;
}
Animal.prototype.speak = function() {
log(this.sound + '! My name is ' + this.name);
};
function Cat(name) {
Animal.call(this, name, 'Meow');
}
Cat.prototype = Object.create(Animal.prototype);
答案 1 :(得分:1)
问题是您在speak
构造函数中将Animal
设置为特权方法。
但是,永远不会为Cat
个实例调用该构造函数。
此外,您不能使用prototype
属性来修改内部[[prototipe]]
并更改应继承属性的对象。您可以使用非标准__proto__
或ECMAScript6 Object.setProtetipeOf
,但最好不要这样做。
相反,更好地使用这种方法:
function SuperClass(args) {
// Here add SuperClass privileged properties
}
// Here add public properties to SuperClass.prototype
function SubClass(otherArgs) {
// Add SuperClass privileged properties to SubClass instances:
SuperClass.call(this, args);
// Here add SubClass privileged properties
}
// Make SubClass instances inherit from SuperClass.prototype:
SubClass.prototype = Object.create(SuperClass.prototype);
// Fix constructor property, overriden in the line above
SubClass.prototype.constructor = SubClass;
// Here add public properties to SubClass.prototype
function log(message) {
document.body.innerHTML += '<p>' + message + '</p>';
}
function Animal(name, sound) {
this.name = name;
this.sound = sound;
}
Animal.prototype.speak = function() {
log(this.sound + '! My name is ' + this.name);
};
function Cat(name) {
Animal.call(this, name, 'Meow');
}
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
var fluffy = new Cat('Fluffy');
fluffy.speak();
&#13;