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