为什么Object.create()在这种情况下用于原型继承?

时间:2017-02-08 01:13:20

标签: javascript prototypal-inheritance

考虑以下代码: -

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;

他们似乎都做了必要的任务。

2 个答案:

答案 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在目标原型之上添加另一个对象。这意味着您可以在不修改原始原型的情况下设置此对象的属性