创建模块的多个实例

时间:2013-02-09 22:15:52

标签: module-pattern revealing-module-pattern javascript

我以为我开始很好地理解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。

如果有人能够解释上述内容是如何运作的,或者让我指出正确的方向,我将不胜感激。感谢

5 个答案:

答案 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)

这就是发生的事情:

  1. init()函数在counter变量上创建了一个闭包,该变量在Test scope中定义,并保存对它的引用。
  2. Test()函数的返回创建了一个新对象,另一个变量counter设置为内部counter的值。
  3. 您通过设置test1.counter = X来更新'另一个'counter,但init()仍保留对原始变量的引用。
  4. 这就是你看到旧价值的原因。

答案 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