我试图理解Javascript的原型继承模型,但似乎缺少某些东西。我创建了以下对象集:
function Dog() {
this.legs = 4;
this.arms = 0;
}
Dog.prototype.describe = function() {
console.log("Has " + this.legs + " legs and " + this.arms + " arms");
}
function Schnauzer(name) {
Dog.call(this);
this.name = name;
}
Schnauzer.prototype.describe = function() {
console.log(this.name + " is a Schnauzer with a shaggy beard");
Dog.prototype.describe(this);
}
var my_dog = new Schnauzer("Rupert");
my_dog.describe();
我的期望是这将输出:
Rupert is a Schnauzer with a shaggy beard
Has 4 legs and 0 arms
但是这实际上是我得到的:
Rupert is a Schnauzer with a shaggy beard
Has undefined legs and undefined arms
使用
Dog.prototype.describe(this);
您正在使用describe
的调用上下文(this
值)调用Dog.prototype
方法,并将dog实例作为第一个参数传递。但是describe
不接受任何参数,它尝试从this
中获取属性。
改为执行Dog.prototype.describe.call(this);
,以狗实例的this
值调用该方法:
function Dog() {
this.legs = 4;
this.arms = 0;
}
Dog.prototype.describe = function() {
console.log("Has " + this.legs + " legs and " + this.arms + " arms");
}
function Schnauzer(name) {
Dog.call(this);
this.name = name;
}
Schnauzer.prototype.describe = function() {
console.log(this.name + " is a Schnauzer with a shaggy beard");
Dog.prototype.describe.call(this);
}
var my_dog = new Schnauzer("Rupert");
my_dog.describe();
还是,这很丑陋,因为您必须使用.call
才能获得一种方法,该方法在正常情况下会在当前对象的原型链上更高。如果可能的话,您可以考虑重新命名您的Schnauzer.prototype.describe
方法,因此它不会使Dog.prototype
方法蒙上阴影:
function Dog() {
this.legs = 4;
this.arms = 0;
}
Dog.prototype.describe = function() {
console.log("Has " + this.legs + " legs and " + this.arms + " arms");
}
function Schnauzer(name) {
Dog.call(this);
this.name = name;
}
Schnauzer.prototype = Object.create(Dog.prototype);
Schnauzer.prototype.describeSchnauzer = function() {
console.log(this.name + " is a Schnauzer with a shaggy beard");
this.describe();
}
var my_dog = new Schnauzer("Rupert");
my_dog.describeSchnauzer();
或使用class
语法和super
:
class Dog {
legs = 4;
arms = 0;
describe() {
console.log("Has " + this.legs + " legs and " + this.arms + " arms");
}
}
class Schnauzer extends Dog {
constructor(name) {
super();
this.name = name;
}
describe() {
console.log(this.name + " is a Schnauzer with a shaggy beard");
super.describe();
}
}
var my_dog = new Schnauzer("Rupert");
my_dog.describe();