JavaScript: 私有成员被另一个实例覆盖

JavaScript: Private members overwritten by another instance

我有这个:

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 */

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

我选择这种带有私有 setter 的模式,以防止成员在 class 本身之外被不必要地更改。

根据我阅读的关于原型设计的内容,这种行为不应该发生。但很明显,我的私有成员被多个实例唯一使用。那我误会了什么?

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

最后构造实例的 _v 变量的引用

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