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?

5 Answers 5

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

var ob = increment();
Sign up to request clarification or add additional context in comments.

8 Comments

+1. @naveen: The noob seems to be heading that way on his/her own. :)
@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: I just agreed with you. :) I, too, was surprised to see the OP, a self-declared beginner, trying to learn closures.
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.
@Vaibhav: The increment function itself doesn't increment anything. It returns a function that does. ob holds that function.
|
3
ob = function f(){  
  ++f.count || (f.count = 1);   // initialize or increment a counter in the function object
  return f.count; 
}

Comments

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

Comments

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/

Comments

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

2 Comments

Hi, how do you re-set this counter to 0?
@Denis There is no reset feature, but you can call makeRangeIterator() again to create a new counter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.