如果我在Firefox中运行这段JavaScript代码:
function Human() {
}
function Engineer(diploma) {
this.diploma = diploma;
}
Engineer.prototype = new Human();// Line A1
Engineer.prototype.constructor = Engineer;
Engineer.prototype.getDiploma = function() {
alert(this.diploma);
};
var engineer = new Engineer("Bridges and Roads");
engineer.getDiploma();
var human = new Human();
human.getDiploma(); // Line A2
标记为“A2”的行将在Firefox控制台中生成错误:
TypeError: human.getDiploma is not a function
另请注意,在A1行,我使用“new”来模拟Engineer继承自Human。这可以在以下JSFiddle中测试:
现在我像这样改变A1线:
function Human() {
}
function Engineer(diploma) {
this.diploma = diploma;
}
Engineer.prototype = Human.prototype;// Line B1
Engineer.prototype.constructor = Engineer;
Engineer.prototype.getDiploma = function() {
alert(this.diploma);
};
var engineer = new Engineer("Bridges and Roads");
engineer.getDiploma();
var human = new Human();
human.getDiploma(); // Line B2
请注意,A1线已被B1线替换。其余的代码是一样的。这一次,如果我运行它,Firefox控制台中没有错误,但我会收到一条警告“Bridges and Roads”(这是对engineer.getDiploma()的调用),另一条警告说“undefined”(其中是B2线的结果)。这也可以在JSFiddle上查看,这里:
我的问题是:为什么会出现这种差异?这样做有什么区别:
Engineer.prototype = new Human();
和此:
Engineer.prototype = Human.prototype;
答案 0 :(得分:3)
后者只是复制引用,使“工程师是人类”和“人类是工程师”都是真的。这通常不是预期的效果。
Engineer.prototype = Human.prototype;
var human = new Human();
/*
engineer ->
(Engineer.prototype & Human.prototype) ->
Object.prototype
*/
var human = new Human();
console.log('getDiploma' in human); // true
console.log(human instanceof Engineer); // true
另一方面,前者仅确定“工程师是人类”。这允许Engineer
将自己的身份和逻辑与其他Human
分开。在这种情况下,包括.getDiploma()
。
Engineer.prototype = new Human();
var engineer = new Engineer("Bridges and Roads");
/*
engineer ->
Engineer.prototype ->
Human.prototype ->
Object.prototype
*/
var human = new Human();
console.log('getDiploma' in human); // false
console.log(human instanceof Engineer); // false
您还可以使用Object.create()
建立prototype
chain,而无需调用构造函数:
Engineer.prototype = Object.create(Human.prototype);
答案 1 :(得分:0)
你的问题是原型继承:
你要拨打的是A2线
human.getDiploma()
但是getDiploma没有出现在Human的原型上。
工程师继承对象Human作为它的原型,但Human不会继承工程师的任何东西。
如果你将getDiploma()作为Human的一个方法,你就可以了:
function Human() {
}
Human.prototype.getDiploma = function() {
alert(this.diploma);
};
function Engineer(diploma) {
this.diploma = diploma;
}
Engineer.prototype = Human.prototype;// Line B1
Engineer.prototype.constructor = Engineer;
var engineer = new Engineer("Bridges and Roads");
engineer.getDiploma(); // "Bridges and Roads"
var human = new Human();
human.getDiploma(); // "undefined"