方法一:
Rectangle.prototype.getArea = function() {
return this.length * this.width;
};
方法2:Rectangle.prototype = {
getArea: function() {
return this.length * this.width;
}
};
以上每种方法的区别和优点是什么?
在第一种情况下,你是添加一个新的属性到一个现有的对象,在第二种情况下,你是覆盖 Rectangle.prototype
与一个新的值(对象)。
重写原型会导致以下后果:
-
来解决Rectangle.prototype.constructor
不再指向Rectangle
。当您使用对象字面量时,它将指向Object
。这很容易通过赋值Rectangle.prototype.constructor = Rectangle;
-
您可能会丢失原型上的所有现有属性(除非您再次添加它们,如
constructor
)。 -
现有的
Rectangle
实例不会受到此更改的影响。它们仍然会引用旧的原型,而不会继承新的方法/属性。 -
instanceof
对现有实例(即rect instanceof Rectangle
)的测试将失败,因为instanceof
比较原型,并且如前一点所述,现有实例保留对旧原型的引用。
如果你在创建任何实例之前设置好原型,那么你就不必关心最后三点了。
以上每种方法的区别和优点是什么?
使用对象文字覆盖原型的唯一优点是语法更简洁。在我看来,它并没有超过它的缺点。
你可以通过合并两个对象来使用对象字面量而不覆盖原型:我如何动态地合并两个JavaScript对象的属性?
第二种方法打破了继承链,并删除了之前添加到原型中的所有属性。
让我们看看我在这个例子中所说的"继承链断裂"是什么意思:
function A(){}
A.prototype.a = function(){}
function B(){}
B.prototype = new A();
B.prototype.b = function(){}
这里的B
实例继承了a
方法。
但是如果你做了
B.prototype = { b: function(){} }
如果Rectangle.prototype
为{}
,则两种方法没有区别