0

I am tasked with creating an arrow function called countTimesCalled that takes no parameters. It has to return the number of times it has been called each time it is invoked. The function should be entirely self-contained.

This is what I have so far, I'd like it to be something along these lines but I can't figure out how to initialize the counter. Any help would be greatly appreciated!

countTimesCalled = () => {
counter = 0;
if (counter == undefined){
    counter = 1;
    return(this.counter)
} else {
    return(this.counter++)
}
nan
  • 25
  • 5
  • 1
    Closures are your friend, think about an iife returning your function. An alternative is storing the counter on the function itself. – ASDFGerte Mar 12 '21 at 21:27

3 Answers3

1

Create an immediately invoked function expression that uses arrow functions and returns your counting arrow function. This way you do not need need the function to refer to itself and the count is completely isolated from the outside:

const countTimesCalled = (count => () => ++count)(0);
  
  
console.log(countTimesCalled());
console.log(countTimesCalled());
console.log(countTimesCalled());
console.log(countTimesCalled());
console.log(countTimesCalled());
const countTimesCalled = (
  count => // <-------------<-------------<-------------+
    () => ++count //                                    |
//  ^^^^^^^^^^^^^ gets assigned to `countTimesCalled`   |
)(0); // -->- passed as argument ->---------->----------+

An expanded version of this is the following:

const countTimesCalled = (
  () => {
    let count = 0;

    return () => {
      count += 1;

      return count;
    };
  }
)();
  
  
console.log(countTimesCalled());
console.log(countTimesCalled());
console.log(countTimesCalled());
console.log(countTimesCalled());
console.log(countTimesCalled());
VLAZ
  • 26,331
  • 9
  • 49
  • 67
0

You could attach a property to the function itself that keeps track of the count:

const countTimesCalled = () => {
  if (!countTimesCalled.count) {
    countTimesCalled.count = 0;
  }

  return ++countTimesCalled.count;
};

console.log(countTimesCalled());
console.log(countTimesCalled());
console.log(countTimesCalled());
KevBot
  • 17,900
  • 5
  • 50
  • 68
  • Without arrow functions, you can create a self-reference, which isn't dependent on the outside closure: `let f = function g() { g.counter = (g.counter ?? 0) + 1; return g.counter; }; f(); let h = f; f = void 0; h();` - the variable containing the function can be changed, without breaking the code. Alternatively, one can always use an iife and a closure of course ;) – ASDFGerte Mar 12 '21 at 21:35
  • 1
    @ASDFGerte Nothing in the answer depends on it being an arrow function. You can do the same thing with `function countTimesCalled() { ... }` – Barmar Mar 12 '21 at 21:40
  • I didn't mean it as "there is something wrong with the answer", but just as a side-note. The difference is, that you'll get an expression, which doesn't use outside variables from its closure. Even with `function c() { if (!c.c) c.c = 0; return ++c.c; }` (as function declaration statement), someone could assign `c = void 0;`, and calling the function would throw. – ASDFGerte Mar 12 '21 at 21:43
  • OP explicitly asked for an arrow function anyways, so it's nothing more than a note. – ASDFGerte Mar 12 '21 at 21:49
0

You can add a property to the function itself to save the number of times it is used

const countTimesCalled = () => {
  countTimesCalled.counter=!countTimesCalled.counter?0:countTimesCalled.counter;
  return ++countTimesCalled.counter ;
}; 

OR without arrow function.

function countTimesCalled () {
  if (!this.counter) {
    this.counter = 0;
  }

  return ++this.counter;
};   

NOTE: But the first code is the best one.

abdo afage
  • 26
  • 4
  • This was super helpful, thank you so much – nan Mar 12 '21 at 22:00
  • @AnnaBotts ... *abdo afage's* 2nd version of course should never be used because via `this.counter` it creates a `counter` variable within the global scope which is considered not the cleanest coding style. – Peter Seliger Mar 12 '21 at 22:10
  • thanks for this note :) – abdo afage Mar 12 '21 at 22:47
  • @abdoafage ... actually the note can be seen as hint for deleting the second example from your answer. The *this* based approach is not helpful in either environment arrow function or function declaration / statement / expression. – Peter Seliger Mar 13 '21 at 08:57