简体   繁体   English

访问 javascript 闭包中的变量

[英]accessing variables in javascript closures

var add = (function () {
    var counter = 0;
    return function () { 
        var reset = function() {
            counter = 0;
        }
        return counter += 1;
    }
})();

This is a self-invoking function that creates a "private" variable.这是一个创建“私有”变量的自调用函数。 How would I create a function reset that will reset the counter to 0?我将如何创建一个函数reset ,将计数器重置为 0? I've tried declaring the function inside the closure, but when I call it using add.reset(), it tells me this method is undefined.我试过在闭包内声明函数,但是当我使用 add.reset() 调用它时,它告诉我这个方法是未定义的。

I would recommend that instead of trying to put the function inside your closure, you put your variable outside your closure, like this:我建议不要尝试将函数放在闭包内,而是将变量放在闭包外,如下所示:

var counter = 0;

var add = function() {
    return counter += 1;
};

var reset = function() {
    counter = 0;
};

That way the variable has proper scope for what you are trying to accomplish with it.这样,变量就有了适当的作用域来处理你试图用它完成的任务。

You should return the reset function as a method of the object returned by the IIFE.您应该将重置函数作为 IIFE 返回的对象的方法返回。 That object needs to be the add function, so put the reset method on it.该对象需要是add函数,因此将 reset 方法放在它上面。 Just do it like you would in a global context, but inside a closure and return the add function, eg:就像在全局上下文中那样做,但在闭包中并返回add函数,例如:

var add = (function(){
  var counter = 0;

  function add(n) {
    counter += n || 0;
    return counter;
  }

  add.reset = function(){
    counter = 0;
    return counter;
  }

  return add;
}())

console.log(add(1)) // 1
console.log(add(4)) // 5
console.log(add.reset()); // 0

However, it would make more sense (to me) to have a counter object that has add and reset methods.但是,(对我而言)拥有一个具有添加重置方法的计数器对象会更有意义。

If you want to explicitly keep the counter declared inside the closure, you need to declare reset (even if you don't give it a value) outside the closure.如果你想显式地保持在闭包内声明的计数器,你需要在闭包外声明 reset(即使你没有给它一个值)。 To use your code, it would look like this:要使用您的代码,它看起来像这样:

var reset;
var add = (function () {
    var counter = 0;
    return function () { 
        reset = function() {
            counter = 0;
        }
        return counter += 1;
    }
})();

Now reset is outside the scope of the add function, so it keeps the value assigned within it!现在 reset 超出了 add 函数的范围,因此它将分配的值保留在其中!

To be fair, though, there's no reason to assign reset every time you can the result of add... It might be better to do something like:但是,公平地说,没有理由在每次添加结果时都分配重置...最好执行以下操作:

var reset;
var add = (function () {
    var counter = 0;
    reset = function() {
        counter = 0;
    }
    return function () { 
        return counter += 1;
    }
})();

Or better still, if you want add.reset() to work:或者更好的是,如果你想让add.reset()工作:

var counter = function () {
    var counter = 0;
    this.reset = function() {
        counter = 0;
    }
    this.add = function () { 
        return counter += 1;
    }
};
var add = new counter();

Then add is a full object, which more or less sounds like what you want.然后 add 是一个完整的对象,它或多或少听起来像你想要的。

Or if you want to stick with the self invoking function:或者,如果您想坚持使用自调用函数:

var add = (function () {
    var counter = 0;
    return function () { 
        this.reset = function() {
            counter = 0;
        }
        return counter += 1;
    }
})();

Would probably work.可能会工作。 It would be a slightly unusual paradigm from what I've seen though...不过,从我所看到的情况来看,这将是一个稍微不寻常的范例......

If you would like to keep the privacy of your current count, here is an answer that uses an object:如果您想保留当前计数的隐私,这里有一个使用对象的答案:

function counter() {
   var count = 0;

   this.reset = function() {
       count = 0;
       return count;
   };

   this.add = function() {
       return ++count;
   };
}

Then for instance:然后例如:

var counter1 = new counter();
counter1.add();
console.log(counter1.add());
console.log(counter1.reset());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM