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
,这会削弱您的封装。
我有这个:
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
,这会削弱您的封装。