如果你替换这行代码
Me.prototype.constructor = Me
使用
console.log(Me.prototype.constructor)
Me.prototype.constructor = Me
你会发现,在进行设置之前,
Me.prototype.constructor
是
You
,因为
Me.prototype
是
You
的实例,这是由于这行代码导致的。
Me.prototype = new You()
因此,带有
// Why?
注释的行是必要的,以“修复”通过这种方式进行继承时给JavaScript带来的错误印象。
基本上,问题出现在您试图使用原型继承来实现经典继承。原型继承适用于对象实例,并且没有“类”或甚至真正的“类型”的概念,但是JavaScript通过整个
new
、
.constructor
和
instanceof
使事情变得更加混乱。
这种情况下更具原型特征的做法是放弃构造函数,而是使用强大的构造函数,即返回所需形式对象的函数:
function begetPart(partNumber, description) {
return Object.create({}, {
number: { value: partNumber },
description: { value: description },
describe: {
value: function () {
alert(this.description);
}
}
});
}
function begetTire(partNumber, speed) {
return Object.create(
begetPart(partNumber, "A tire"),
{
speed: { value: speed },
describe: {
value: function () {
alert(this.description + "; speed = " + this.speed);
}
}
}
);
}
var genericPart = begetPart(1234, "A widget");
genericPart.describe();
var tire = begetTire(4567, "fast");
tire.describe();
在这里,我们使用
Object.create
来表示“基于另一个对象实例创建一个对象实例”。对于
begetPart
,另一个实例是一个新的空对象;对于
begetTire
,则是一个预先填充了一些属性的新“部件实例”。
这种方式更好地反映了 JavaScript 和原型继承的实际工作方式,因为在原型继承中,对象实例继承自其他对象实例,而不会被 “类型” 或 “类” 的概念所束缚。
.constructor
属性以使用instanceof
关键字。 - Raynos