方法1:
Rectangle.prototype.getArea = function() {
return this.length * this.width;
};
方法2:
Rectangle.prototype = {
getArea: function() {
return this.length * this.width;
}
};
上述每种方法的不同之处和优点是什么?
答案 0 :(得分:4)
第二个会破坏继承链并删除之前添加到原型中的所有属性。
让我们通过这个例子来看看“继承链中断”的含义:
function A(){}
A.prototype.a = function(){}
function B(){}
B.prototype = new A();
B.prototype.b = function(){}
此处的B
实例会继承a
方法。
但如果你这样做
B.prototype = { b: function(){} }
然后情况就不再如此了。
答案 1 :(得分:4)
在第一种情况下,您将新属性添加到现有对象,在第二种情况下,您使用新值覆盖 Rectangle.prototype
)。
覆盖原型会产生以下后果:
Rectangle.prototype.constructor
不再指向Rectangle
。当您使用对象文字时,它将指向Object
。通过分配
Rectangle.prototype.constructor = Rectangle;
您可能会丢失原型上的所有现有属性(除非您再次添加它们,例如constructor
)。
Rectangle
的现有实例不会受到更改的影响。他们仍然会引用旧的原型,并且不会继承新的方法/属性。
instanceof
对现有实例(即rect instanceof Rectangle
)的测试将失败,因为instanceof
会比较原型和在前一点中提到,现有实例保留了对旧原型的引用。
如果在创建任何实例之前设置原型,那么您不必关心最后三点。
上述每种方法的不同之处和优点是什么?
使用对象文字覆盖原型的唯一优势是更简洁的语法。 IMO虽然没有超过缺点。
您可以通过合并两个对象来使用对象文字而不覆盖原型:How can I merge properties of two JavaScript objects dynamically?。
答案 2 :(得分:1)
如果Rectangle.prototype
为{}
,则两种方法之间没有区别。