admin管理员组

文章数量:1399905

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? I've tried declaring the function inside the closure, but when I call it using add.reset(), it tells me this method is undefined.

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? I've tried declaring the function inside the closure, but when I call it using add.reset(), it tells me this method is undefined.

Share Improve this question edited May 27, 2020 at 20:17 pppery 3,81425 gold badges37 silver badges50 bronze badges asked Jul 26, 2015 at 23:17 bluejay5bluejay5 651 silver badge6 bronze badges 2
  • You can't access a local variable from outside its scope. You need to expose it somewhere. – SLaks Commented Jul 26, 2015 at 23:21
  • Hi bluejay5, if you feel that we have answered your question fully, don't forget to mark an answer as accepted by using the gray checkmark next to the answer! – Maximillian Laumeister Commented Jul 28, 2015 at 1:49
Add a ment  | 

4 Answers 4

Reset to default 5

You should return the reset function as a method of the object returned by the IIFE. That object needs to be the add function, so put the reset method on it. Just do it like you would in a global context, but inside a closure and return the add function, e.g.:

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.

I would remend 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 acplish with it.

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. 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!

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:

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.

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());

本文标签: accessing variables in javascript closuresStack Overflow