考虑以下代码: -
function Rectangle(length, width) {
this.length = length;
this.width = width;
}
Rectangle.prototype.getArea = function() {
return this.length * this.width;
};
function Square(size) {
Rectangle.call(this, size, size);
}
Square.prototype = Object.create(Rectangle.prototype);
var rect = new Rectangle(5, 5);
var square = new Square(7);
console.log(rect.getArea()); // 25
console.log(square.getArea()); // 49
为什么我们必须这样做继承: -
Square.prototype = Object.create(Rectangle.prototype);
而不是这样: -
Square.prototype = Rectangle.prototype;
他们似乎都做了必要的任务。
答案 0 :(得分:4)
设置Square.prototype = Rectangle.prototype
意味着它们都是同一个对象,这几乎肯定不是你想要的。 Square是一个Rectangle,但Rectangle不是Square,因此行为将不相同。你需要两个不同的原型对象。
使用Object.create()
是一种创建对象的简洁方法,该对象具有给定对象(在本例中为Rectangle.protoype
)作为其原型链的头部。结果是Square.prototype
是一个独特的对象,并且可以给它自己的属性(适用于正方形而不是矩形的特殊方法),但它也可以访问Rectangle原型中的方法。
因此,当您通过new Square(100)
创建一个Square时,您将获得一个对象,其直接原型是使用Object.create()
创建的对象,并且(可能)用各种有趣的Square行为进行修饰。 反过来,对象的Rectangle.prototype
是其原型链中的第一件事。这样做的结果是,如果你调用,例如mysquare.area()
,并且在Rectangle原型上定义了area()
,则查找将从Square实例,Square原型,然后到Rectangle继续。原型将找到方法。
答案 1 :(得分:2)
Object.create在目标原型之上添加另一个对象。这意味着您可以在不修改原始原型的情况下设置此对象的属性