0

The following code will allow the counter function to be incremented by one every time counter(); is called.

function One() {  
    var counter = function(initial) {
        var c = initial || 0;
        return function() {
            return c++;
        };
    }(0);
    Too(counter);
}

function Too(counterArg) {
    counter();
}

Is there any thing I can replace counter(); with so the counter will decrement? Or even better is there any way for me to set the value of the counter? Like counter = 0 or counter = 20? Also I need to stay away from global variables.

Kahless
  • 1,213
  • 2
  • 13
  • 31

2 Answers2

2

you can assign function as a variable in javascript so now you can do this...

var counter = 0;
var step = 1; // or 20 or whatever
var method = null;

function increment () {
  counter += step;
}

function decrement () {
  counter -= step;
}

method = icrement;
method();
Dmitry Matveev
  • 5,320
  • 1
  • 32
  • 43
1

First, you have a minor typo in your code; presumably you mean

function Too(counterArg) {
    counterArg();  // this was just `counter` originally; that will be undefined
}

Second, c++ is a little bit of a weird way to do a counter, since it return c and then increment c, so the counter will start at 0 which is probably not what you want. (I admit I chuckle a little bit whenever I see c++ in code though. :P )

Okay, on to the main question: I'd do it by adding a method to the counter function called e.g. set.

function One() {  
    var counter = function createCounter(initial) {
        var c = initial || 0;
        function counter() {
            return ++c;
        }
        counter.set = function(n) {
            c = n;
        };
        return counter;
    }(0);
    Too(counter);
}

function Too(counterArg) {
    counter(); // 1
    counter.set(20);  // `c` is now 20
    counter(); // 21
    counter(); // 22
}

This works because the counter function creates what's called a closure. This is a fairly common concept in JavaScript and there are plenty of good questions and answers about closures on SO that you should look at if you don't know the concept. Basically, even after your anonymous function (which I renamed createCounter) returns, the variable c still exists and can be accessed from any code in createCounter. That's how the counter function works. c cannot, however, be accessed by any code outside createCounter, so if you want to do anything with it, you have to put that code in createCounter. That's what the counter.set method I added does. Since it's within createCounter, it is free to modify c.

Peter C
  • 6,219
  • 1
  • 25
  • 37
  • This works perfectly. Thanks for the help and the tip about closures. I'm going to read up on that. – Kahless Oct 18 '13 at 18:57
  • They're a little bit confusing initially, but a very simple and useful concept once you get the hang of it. This answer on SO is pretty amazing: http://stackoverflow.com/a/111111/470535 – Peter C Oct 18 '13 at 19:00