这些原型声明的区别是什么?



方法一:

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{},则两种方法没有区别

相关内容

最新更新