Javascript对象构造:有什么区别?

Javascript对象构造:有什么区别?,javascript,oop,Javascript,Oop,除了成员变量的隐私之外,这两个对象的构造有什么不同 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; }

除了成员变量的隐私之外,这两个对象的构造有什么不同

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; }
   }
}
我对成员变量的隐私不感兴趣,而是对函数的定义方式感兴趣

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

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

还有,是一种方式优于另一种方式,还是还有更好的方式

非常感谢

我认为在第二个版本中,所有对象都被创建了,这对吗 via new A()将获取已定义函数的副本,其中 第一个版本所有对已定义函数的调用都将转到 并且只有原型对象(对于A对象)。是这样吗

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

setA和getA对每个对象A的内存使用率更高

还有,是一种方式比另一种方式更受欢迎,还是有更好的方式 又来了


由于您不关心封装,请使用prototype(原型)

除了内部变量的隐私之外,它们的行为应该类似,但您是正确的,第二个版本将比第一个版本使用更多内存。除非处理大量对象,否则这通常是微不足道的,但使用原型方法时,只有一个getA和setA函数,而使用第二种方法时,每个方法都有自己的函数用于这些方法。

这两个方面都是正确的

因此,性能差异将是内存消耗——第二种方法将为每个对象消耗更多的内存。此外,在第二个版本中,每个对象的创建/实例化可能需要稍长或更长的时间,因为您必须创建那些消耗内存的函数,尽管这是可以忽略的(在这个玩具案例中),甚至可能会被依赖于实现的因素所抵消


我建议使用原型方法,因为基于这些原因,它的伸缩性稍好一些。关于可见性,甚至可以用ES5以原型方式伪实现。

第一种方法将这些函数定义为
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
当使用第二种方法时,不能这样做

第二种方法的优点是函数捕获构造函数的上下文,因此您可以在构造函数中拥有私有变量和函数,然后这些变量和函数可以由您的函数使用

这不能用原型上定义的函数来完成


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

setter和getter是一个可怕的想法。停止将Java代码移植到javascript。@Raynos,不太可怕,不能包含在ES5中。@davin,这是不同的。那些是天生的能手(他们仍然是邪恶的)。像
setA
getA
这样的仿真对象是非常愚蠢的。本机getter/setter实际上应该只用于做真正聪明的事情,而不是在每天code@Raynos你在开玩笑吗?JavaScript让这个行业落后了20年,而推广此类评论的人都被[审查]+1用于很好地总结差异并建议何时使用每种差异。