3

方法一:

Rectangle.prototype.getArea = function() {
     return this.length * this.width;
};

方法二:

Rectangle.prototype = {
     getArea: function() {
          return this.length * this.width;
     }
};

上述每种方法的区别和优点是什么?

4

3 回答 3

4

第二个破坏了继承链并删除了您之前添加到原型中的所有属性。

让我们用这个例子来看看我所说的“继承链中断”是什么意思:

function A(){}
A.prototype.a = function(){}
function B(){}
B.prototype = new A();
B.prototype.b = function(){}

这里的一个实例B继承了该a方法。

但如果你这样做

B.prototype = { b: function(){} }

那么情况就不再如此了。

于 2013-05-27T12:20:57.420 回答
4

在第一种情况下,您正在向现有对象添加新属性,在第二种情况下,您正在用新值(对象)覆盖。 Rectangle.prototype

覆盖原型会产生以下后果:

  • Rectangle.prototype.constructor不再指向Rectangle。当您使用对象文字时,它将指向Object。这可以通过分配轻松解决

    Rectangle.prototype.constructor = Rectangle;
    
  • 您可能会丢失原型上的所有现有属性(除非您再次添加它们,例如使用constructor)。

  • 的现有实例Rectangle不会受到更改的影响。他们仍然会引用旧的原型并且不会继承新的方法/属性。

  • instanceof现有实例(即rect instanceof Rectangle)的测试将失败,因为instanceof比较原型,并且如前所述,现有实例保持对旧原型的引用。

如果您在创建任何实例之前设置原型,那么您不必关心最后三点。

上述每种方法的区别和优点是什么?

使用对象文字覆盖原型的唯一优点是语法更简洁。IMO 它并没有超过缺点。

您可以通过合并两个对象来使用对象字面量而不覆盖原型:如何动态合并两个 JavaScript 对象的属性?.

于 2013-05-27T12:22:51.510 回答
1

如果Rectangle.prototype{},这两种方法没有区别。

于 2013-05-27T12:21:21.937 回答