6

I'm a beginner with JavaScript so please be patient =)

I am trying to write a function that counts the number of times it is called. What I have so far is a function with a counter that is incremented explicitly:

var increment = function () {
    var i = 0;
    this.inc = function () {i += 1;};
    this.get = function () {return i;};
};

var ob = new increment();
ob.inc();
ob.inc();
alert(ob.get());

But I'm wondering how to call only ob();, so the function could increment calls made to itself automatically. Is this possible and if so, how?

Ray Toal
  • 86,166
  • 18
  • 182
  • 232
Kamil
  • 61
  • 1
  • 1
  • 2

5 Answers5

8
var increment = function() {
    var i = 0;
    return function() { return i += 1; };
};

var ob = increment();
Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • 1
    +1. @naveen: The noob seems to be heading that way on his/her own. :) – Shef Aug 30 '11 at 12:38
  • @Shef: I said its good. Its a while before I realized there were closures. But then js was my secondary language. a tiny perk that has alertboxes :) – naveen Aug 30 '11 at 12:43
  • 1
    @naveen: I just agreed with you. :) I, too, was surprised to see the OP, a self-declared beginner, trying to learn closures. – Shef Aug 30 '11 at 12:50
  • The OP's code is almost identical to one of my first attempts to learn JS. Being a noob JS programmer doesn't imply being a noob programmer. – Marcelo Cantos Aug 30 '11 at 12:57
  • @Marcelo Cantos: dont understand your's laugh cuz that what u wrote isn't increment ... ? Nice work Mr A lot of experience in OP – Kamil Sep 01 '11 at 19:28
  • @Kamil: Try invoking `alert(ob())` a couple of times. – Marcelo Cantos Sep 01 '11 at 23:05
  • @MarceloCantos : I am noon myself :) . I just want to know the reason why do we have to use var ob = increment(); and then call ob(); to increase the 'counter' value. Why does it not increment the counter value if we directly call the increment() function ? – Vaibhav Pachauri Apr 13 '15 at 15:04
  • 2
    @Vaibhav: The increment function itself doesn't increment anything. It returns a function that does. `ob` holds that function. – Marcelo Cantos Apr 14 '15 at 09:48
3
ob = function f(){  
  ++f.count || (f.count = 1);   // initialize or increment a counter in the function object
  return f.count; 
}
aljgom
  • 7,879
  • 3
  • 33
  • 28
2

A one liner option:

const counter = ((count = 0) => () => count++)()

Usage example:

> counter()
0
> counter()
1
> counter()
2
> counter()
3
> counter()
4
> counter()
5
> counter()
6
paulodiovani
  • 1,208
  • 2
  • 16
  • 34
1

Wrap a counter to any function:

/**
 * Wrap a counter to a function
 * Count how many times a function is called
 * @param {Function} fn Function to count
 * @param {Number} count Counter, default to 1
 */
function addCounterToFn(fn, count = 1) {
  return function () {
    fn.apply(null, arguments);
    return count++;
  }
}

See https://jsfiddle.net/n50eszwm/

pldg
  • 2,427
  • 3
  • 22
  • 37
1

There are also the new Generator functions, which offer a simple way to write a counter:

function* makeRangeIterator(start = 0, end = 100, step = 1) {
  let iterationCount = 0;
  for (let i = start; i < end; i += step) {
    iterationCount++;
    yield i;
  }
  return iterationCount;
}

const counter = makeRangeIterator();
const nextVal = () => counter.next().value;

console.log("nextVal: ", nextVal()); // 0
console.log("nextVal: ", nextVal()); // 1
console.log("nextVal: ", nextVal()); // 2
console.log("nextVal: ", nextVal()); // 3
terrymorse
  • 6,771
  • 1
  • 21
  • 27