2011-09-20 90 views
4

这两个对象的构造有什么区别 - 除了成员变量的隐私?Javascript对象构造:有什么区别?

function A() { this.a = 99; } 
A.prototype.setA = function(newVal) { this.a = newVal; } 
A.prototype.getA = function({ return this.a; } 

这:

function A() { 
    var a = 99; 
    return { 
     setA: function(newVal) { a=newVal; } 
     getA: function() { return a; } 
    } 
} 

我不感兴趣的成员变量这么多的功能被定义方式的隐私。

我是否认为在第二个版本中,通过新的A()创建的所有对象都会获得已定义函数的副本,在第一个版本中,所有对已定义函数的调用将转到唯一原型对象(对于A对象)。这是正确的吗?

如果是这样,版本2有任何性能成本?

另外,一种方式是否优于另一种 - 或者还有更好的方法吗?

非常感谢

+0

安装者和吸气者是一个可怕的想法。停止将Java代码移植到JavaScript。 – Raynos

+0

@Raynos,不太可怕,不会被纳入ES5。 – davin

+0

@达文这是不同的。这些是本地的getter/setter(他们仍然是邪恶的)。像'setA'和'getA'这样的模拟器是非常愚蠢的。 Native Native getter/setters应该只用于做真正聪明的事情,而不是每天都在使用代码 – Raynos

回答

6

我是正确的思维,在第二版中的所有对象通过new A()创建 将获得的定义的函数,其中作为 第一个版本调用所有副本定义的函数将会转到一个 并且只有原型对象(对于A对象)。这是正确的吗?

如果是这样就第2版有任何性能成本?与组A和每个对象的木屐

更多的内存使用量的

而且,是一种方式优于另一种 - 或者是有没有更好的办法 一遍吗?

既然你不关心封装,使用原型

1

内变量一旁的隐私,这些行为应该相似,但你是正确的,第二个版本将使用更多的内存比第一。这通常是微不足道的,除非你使用大量的对象,但使用原型方法只有一个getA和setA函数,而第二种方法每个都有自己的这些方法的函数。

1

你在两个帐户上都是正确的。

因此,性能差异将是内存消耗 - 第二种方式会消耗更多的每个对象。另外,在第二个版本中,每个对象的创建/实例可能会稍微延长一点,因为你必须创建那些耗费内存的函数,尽管这个可以忽略不计(在这个玩具的情况下),甚至可能被实现相关的因素所抵消。

我会建议原型方法,因为这些原因,它略微好一些。关于能见度,甚至可以用ES5以原型的方式伪造实施。

2

第一种方法将这些函数定义为A.prototype对象的属性,这意味着对于A的所有实例,这些函数在一个位置中定义。

第二种方法直接在实例对象上定义函数(作为属性),这意味着您将为每个创建的实例(=更高的内存消耗)提供一组新的函数。

第一种方法的优点是,您可以根据需要影子继承方法

A.prototype.foo = function() { ... }; 

var a = new A; 
a.foo(); // inherited 
a.foo = function() { ... }; 
a.foo(); // shadowed 
delete a.foo; 
a.foo(); // back to inherited 

在使用第二种方法时,不能这样做。

第二种方法的优点是功能捕捉构造的情况下,这样你就可以在其中,然后可以通过你的函数用来构造私有变量和函数。

这不能与原型定义的函数来完成。


所以我的建议是: 如果您需要私有变量或函数,使用第二种方法。否则,使用原型。

+0

+1用于很好地总结差异并推荐何时使用它们。 – jfriend00

相关问题