我以为我开始很好地理解JavaScript,但显然不是。让我用一个例子来解释我的问题。首先,我定义了以下模块:
var Test = function() {
var counter = 0;
function init() {
alert(counter);
}
return {
counter: counter,
init: init
}
};
然后我创建了2个实例:
var test1 = new Test();
var test2 = new Test();
现在我更新计数器变量(因为它是公共的)并做一些警报。到目前为止一切都很好。
alert(test1.counter); // Alerts 0
test1.counter = 5;
alert(test2.counter); // Alerts 0
test2.counter = 10;
alert(test1.counter); // Alerts 5
现在终于说出以下内容:
test1.init(); // Alerts 0
test2.init(); // Alerts 0
这是我不明白的一点。为什么这个警报0?我认为第一个警报是5,第二个是10。
如果有人能够解释上述内容是如何运作的,或者让我指出正确的方向,我将不胜感激。感谢
答案 0 :(得分:12)
它保持0
是因为您没有更改Test
内的变量,而是更改函数返回的对象。 counter
保持“私密”状态,只有Test
中的某个功能才能访问它。
var Test = function() {
var counter= 0;
function init() {
alert(counter);
}
function changeNum(n){
counter = n; //add a function inside `Test` so that it can
} //access the variable
return {
counter: counter,
init: init,
changeNum: changeNum
}
};
现在它将起作用:http://jsfiddle.net/DerekL/pP284/
var test1 = new Test();
alert(test1.counter); //0
test1.init(); //0
test1.changeNum(5);
alert(test1.counter); //5
test1.init(); //5
有关详细信息,请参阅JavaScript Closures。
答案 1 :(得分:5)
这就是发生的事情:
counter
变量上创建了一个闭包,该变量在Test scope中定义,并保存对它的引用。counter
设置为内部counter
的值。counter
,但init()仍保留对原始变量的引用。这就是你看到旧价值的原因。
答案 2 :(得分:3)
我不确定你的帖子是否犯了错误,但你可以按如下方式重写上述代码
var Test = function() {
this.counter = 0;
}
Test.prototype.init = function() {
alert(this.counter);
}
var test1 = new Test();
var test2 = new Test();
test1.counter = 5;
test2.counter = 10;
test1.init(); // alerts 5
test2.init(); // alerts 10
在您的示例中,您没有将计数器设置为Test对象/函数的属性,而是在调用test1.counter
时实际上是在设置之前不存在的新属性,并且初始化函数未引用该属性。
正如dereks的答案显示的那样,你似乎对我的答案和他的答案之间的两种不同模式略有混淆。
答案 3 :(得分:1)
alert(test1.counter); // Alerts 0 ????? It's "0" because you call it before change counter to 5
test1.counter = 5;
alert(test2.counter); // Alerts 0 ????? It's "0" because you call it before change counter to 10
test2.counter = 10;
alert(test1.counter); // Alerts 5 | It's 5 because you call it AFTER change counter to 5
答案 4 :(得分:0)
以下是我要做的事情:
function Test() {
this.counter = 0;
this.init = function() { console.log(this.counter); }
};
var test1 = new Test();
var test2 = new Test();
console.log(test1.counter); //0
test1.counter = 5;
console.log(test2.counter); //0
test2.counter = 10;
console.log(test1.counter); //5
test1.init(); //5
test2.init(); //10