如果我在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中对其进行测试:

http://jsfiddle.net/RMWdh/1/

现在,我像这样更改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控制台中没有错误,但是我将收到一个警报,提示“桥梁和道路”(这是对engineering.getDiploma()的调用),以及另一个警报,提示“未定义”(其中是B2行的结果)。也可以在JSFiddle上检查,这里:

http://jsfiddle.net/RMWdh/2/

我的问题是:为什么会有这种差异?这样做之间有什么区别:

 Engineer.prototype = new Human();


和这个:

 Engineer.prototype = Human.prototype;

最佳答案

后者只是复制了引用,使“工程师是人类”和“人类是工程师”均为真。通常这不是所需的效果。

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);

07-26 08:47