0

const Formatter = (function() {
  let timesRun = 0;
  
  const log = (message) => console.log(`[${Date.now()}] Logger: ${message}`);
  const setTimesRun = () => {
    log("Setting times run");
    ++timesRun;
    console.log(timesRun);
  }

  const makeUppercase = (text) => {
    log("Making uppercase");
    setTimesRun();
    return text.toUpperCase();
  };

  return {
    makeUppercase,
    timesRun,
  }
})()

console.log(Formatter.makeUppercase("tomek"));
console.log(Formatter.timesRun);

console.log(Formatter.makeUppercase("foo"));
console.log(Formatter.timesRun);

console.log(Formatter.makeUppercase("hey"));
console.log(Formatter.timesRun);

With console.log(Formatter.timesRun); I'm expecting the incremented value of timesRun. However, it keeps logging 0. Using console.log(timesRun); inside the setRimesRun() function logs the incremented value. I don't understand where the data is stored and why am I getting 0.

I thought timesRun was always 0 and I added console.log(timesRun); to test it. It showed the incremeneted value which confused the me even more.

ponury-kostek
  • 7,824
  • 4
  • 23
  • 31
Metal
  • 3
  • 1
  • You're storing numbers in two separate locations: the variable and the object property. – Bergi Mar 17 '23 at 09:57
  • The `timesRun` property in `{makeUppercase, timesRun}` is a copy of the number in `let timesRun`, copied when you created the return value from the function. It won't change if you set (separate variable) `timesRun` to something else. Simpler example: `let timesRun = 4; let temp = {timesRun}; timesRun = 8; //temp.timesRun is still 4, the value of the property when it was created` – qrsngky Mar 17 '23 at 10:00

2 Answers2

0

The variable timesRun is locally in the method setTimesRun. You should use the one outside of setTimesRun, so Formatter.timesRun.

You can do like that:

const Formatter = (function() {
  var timesRun = 0;
  const log = (message) => console.log(`[${Date.now()}] Logger: ${message}`);
  const setTimesRun = () => {
    Formatter.timesRun++;
    log("Setting times run to " + timesRun);
    //console.log(timesRun);
  }

  const makeUppercase = (text) => {
    log("Making uppercase");
    setTimesRun();
    return text.toUpperCase();
  };

  return {
    makeUppercase,
    timesRun,
  }
})()

console.log(Formatter.makeUppercase("tomek"));
console.log(Formatter.timesRun);

console.log(Formatter.makeUppercase("foo"));
console.log(Formatter.timesRun);

console.log(Formatter.makeUppercase("hey"));
console.log(Formatter.timesRun);

Here, all times I'm using the same variable: Formatter.timesRun. With this, all logger use the same and will some same instance of this int

Elikill58
  • 4,050
  • 24
  • 23
  • 45
0

your misunderstanding: var a = 5, b = a; then a = 10; and wondering why b is still 5 and not 10? Formatter.timesRun is not the same thing as let timesRun which you increment.
The variable changes, but you never update the object property.

Check out getter

const Formatter = (function() {
  let timesRun = 0;
  
  const log = (message) => console.log(`[${Date.now()}] Logger: ${message}`);
  const setTimesRun = () => {
    log("Setting times run");
    ++timesRun;
    console.log(timesRun);
  }

  const makeUppercase = (text) => {
    log("Making uppercase");
    setTimesRun();
    return text.toUpperCase();
  };

  return {
    makeUppercase,
    get timesRun(){
      return timesRun
    },
  }
})()

console.log(Formatter.makeUppercase("tomek"));
console.log(Formatter.timesRun);

console.log(Formatter.makeUppercase("foo"));
console.log(Formatter.timesRun);

console.log(Formatter.makeUppercase("hey"));
console.log(Formatter.timesRun);
Thomas
  • 11,958
  • 1
  • 14
  • 23