2013-05-27 49 views
3

方法1:这些原型声明有什么区别?

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

方法2:

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

各有什么上述方法的区别和优点?

+2

与使用普通对象一样,第二种样式破坏'prototype'的所有现有内容。 – DCoder

+4

这与'x + = 10'和'x = 10'基本相同。 – georg

+0

另请参见[定义Javascript原型](http://stackoverflow.com/questions/17474390/defining-a-javascript-prototype) – Bergi

回答

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?

+0

感谢您的详细解释。得到它了! – user2424941

4

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

让我们看看我所说的“继承链断裂”这个例子的意思是:

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

B实例这里继承a方法。

但是,如果你

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

那么这不再是这种情况。

+0

谢谢!现在更有意义 – user2424941

1

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