这个问题是关于一个对象的行为,其方法添加到其原型链和一些私有变量。只是出于好奇,让我的头围绕这个谜语。
function SomeObject() {
if (this instanceof SomeObject) {
var args = arguments[0],
proto = SomeObject.prototype,
privatevalue = 0,
/** assign first element of args[0]
* (=instance name) to private variable [id],
* to be able to keep track of the instance
*/
id = args[0] ||'no id';
/** public 'set' adds a value to
* the private variable [privatevalue]
*/
this.set =
function(){
privatevalue += arguments[0] || 1;
return privatevalue;
};
/** toString functions as a kind of getter */
this.toString = function(){
return id+' privatevalue: '+privatevalue;
}
/** add two methods to the prototype chain
* this happens only once
*/
if (!proto._initialized_) {
/** SomeObject.prototype.add
* uses 'this.set' to add a value
* to [privatevalue] and returns
* the object value (from tostring)
*/
proto.add =
function(){
this.set(arguments[0]);
return this;
};
/** SomeObject.prototype.add2
* uses 'this.set' to add a value
* to [privatevalue] but returns
* a string using private variables
* [id] and [privatevalue]
*/
proto.add2 =
function(){
this.set(arguments[0]);
return id+' privatevalue: '+privatevalue;
};
proto._initialized_ = true;
}
} else {
return new SomeObject(Array.prototype.slice.call(arguments));
}
}
/** create 2 instances of SomeObject */
var objA = SomeObject('objA'),
objB = SomeObject('objB');
/** show the values and use the prototype [add] method
* to change [privatevalue]
*/
alert ([objA, objB].join(' | '));
//=> objA privatevalue: 0 | objB privatevalue: 0
alert ([objA.add(4), objB.add(2)].join(' | '));
//=> objA privatevalue: 4 | objB privatevalue: 2
/** use prototype method 'add2' to change and view the
* private variables [id] and [privatevalue] for objA
*/
alert (objA.add2());
//=> objB privatevalue: 2!
现在问题是:为什么来自ojbA的原型方法add2(因此:objA.add2())从objB返回私有变量的值?我想说objA不应该使用这些私有。换句话说:这里有什么样的范围? 更奇怪的是。如果你这样做:
alert (objA.add2());
alert (objB.add2());
你得到的是objA.add2():objA privatevalue: 5
和objB.add():objA privatevalue: 5
答案 0 :(得分:1)
问题是您创建添加功能的范围。
当您实例化'objA'时,它们是在SomeObject执行的范围内创建的。
因此Add2访问的id和privatevalue变量是属于'objA'的变量,无论你是否调用.Add2再次'objA'或'objB'。
基于Fundementally原型的方法无法访问类的私有成员。为了访问私有成员,需要在这些成员的相同范围(或子范围)中创建函数。这就是为什么set有效,因为它是在SomeObject的每个实例上创建的。