JavaScript:由其他实例覆盖的私有成员

时间:2015-06-11 08:25:43

标签: javascript private-members prototyping

我有这个:

var Foo = function( v )
{
  /* Private member for shorthand prototyping */
  var _prototype = Foo.prototype;

  /* Private member */
  var _v = null;

  /* Public getter */
  _prototype.vGet = function( )
  {
    v = _v;
    return v;
  };

  /* Private setter */
  var vSet = function( v )
  {
    _v = v;
  };

  /* Constructor closure */
  ( function( v )
  {
    vSet( v );
  } )( v );
};

var f1 = new Foo( 10 );
console.log( 'f1::' + f1.vGet( ) );  /* f1::10 */
var f2 = new Foo( 20 );
console.log( 'f2::' + f2.vGet( ) );  /* f2::20 */
console.log( 'f1::' + f1.vGet( ) );  /* f1::20 */

所以我的问题很明显。在Foo中创建f2的第二个实例后,f1._v也在发生变化。

我选择使用私有设置器的这种模式,以防止在类本身之外更改不需要的成员。

通过我读到的关于原型的内容,不应该发生这种行为。但是显然我的私有成员被多个实例唯一使用。那么我误解了什么?

1 个答案:

答案 0 :(得分:4)

您的问题是,每次构建Foo.prototype.vGet的新实例时,都会重新定义Foo。原型在Foo的所有实例之间共享,但重新定义的vGet函数包含对_v的最后构造实例的Foo变量的引用。

解决方案是将Foo.prototype.vGet = ...更改为Foo.vGet,从而每次都创建一个新函数。或者将赋值移到构造函数之外,例如使用this._v而不是_v,这会削弱您的封装。