0
// constructor
function IceCream() {
  this.scoops = 0;
}

// adds scoop to ice cream
IceCream.prototype.addScoop = function() {
  const cone = this; // sets `this` to the `cone` variable
  setTimeout(function() {
    cone.scoops++; // references the `cone` variable
    console.log('scoop added!');
  }, 0.5);
};

const dessert = new IceCream();
dessert.addScoop();
console.log(dessert.scoops);

In this code my expectation for the output of console.log(dessert.scoops) is to be 1 but it returns 0.

Can anyone give me some valid reason?

RubioRic
  • 2,442
  • 4
  • 28
  • 35
praveen-me
  • 486
  • 3
  • 10

1 Answers1

1

setTimeout works asynchronously, meaning the contents will be called when your current execution is completed and it moves to the next event in the event loop.

By reading the value immediately after calling the method, the closure has not been called yet. You either

  1. Have to remove the closure all together and do it synchronously in the addScoop function. Or,
  2. Ensure you read it after the closure was called. Since you are using es6, promises are available.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Creating_a_Promise

// constructor
function IceCream() {
  this.scoops = 0;
}

// adds scoop to ice cream
IceCream.prototype.addScoop = function() {
  const cone = this; // sets `this` to the `cone` variable
  return new Promise(function(resolve) {
    cone.scoops++;
    console.log('scoop added!');
    resolve();
  });
};

const dessert = new IceCream();
dessert.addScoop().then(function() {
    console.log(dessert.scoops);
});
Coloured Panda
  • 3,293
  • 3
  • 20
  • 30