【问题标题】:What is the difference between these prototype declaration? [duplicate]这些原型声明有什么区别? [复制]
【发布时间】:2013-05-27 12:17:51
【问题描述】:

方法一:

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

方法二:

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

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

【问题讨论】:

  • 与处理普通对象时一样,第二种样式会破坏prototype的所有现有内容。
  • 这与x += 10 vs x = 10基本相同。

标签: javascript oop prototype


【解决方案1】:

在第一种情况下,您添加新属性到现有对象,在第二种情况下,您覆盖 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】:

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

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

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

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

如果你这样做了

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

那就不是这样了。

【讨论】:

  • 谢谢!现在更有意义了
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 2016-05-08
    • 2014-04-10
    • 2020-07-22
    • 2010-09-18
    • 2014-04-14
    • 2015-12-22
    相关资源
    最近更新 更多