Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access variables in another scope inside a function using closure in javascript?

I have the following function makeStopwatch that I am trying to work through to better understand javascript closures:

var makeStopwatch = function() {
  var elapsed = 0;
  var stopwatch = function() {
    return elapsed;
  };
  var increase = function() {
    elapsed++;
  };

  setInterval(increase, 1000);
  return stopwatch;
};

var stopwatch1 = makeStopwatch();
var stopwatch2 = makeStopwatch();

console.log(stopwatch1());
console.log(stopwatch2());

When I console.log the calls to stopwatch1 and stopwatch2 I get 0 returned each time respectively.

As I understand the intended functionality of makeStopwatch the variable elapsed would be 0 if returned by the inner function stopwatch. The inner function increase increments the variable elapsed. Then setInterval calls increase after a delay of 1 second. Finally, stopwatch is returned again this time with the updated value which is expected to be 1.

But this doesn't work because inside makeStopwatch, the inner stopwatch, increase, and setInterval functions are all in independent scopes of one another?

How can I revise this to work as I understand it so that elapsed is incremented and that value is closed over and saved so that when I assign makeStopwatch to variable stopwatch1 and call stopwatch1 the updated value is returned?

like image 202
phizzy Avatar asked Jul 11 '15 04:07

phizzy


People also ask

What kind of access closure variable have?

A closure is a feature in JavaScript where an inner function has access to the outer (enclosing) function's variables — a scope chain. The closure has three scope chains: it has access to its own scope — variables defined between its curly brackets. it has access to the outer function's variables.

What is a closure and how does it relate to scope?

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function.

How do you closure a function in JavaScript?

This is called a JavaScript closure. It makes it possible for a function to have "private" variables. The counter is protected by the scope of the anonymous function, and can only be changed using the add function. A closure is a function having access to the parent scope, even after the parent function has closed.


1 Answers

var makeStopwatch = function() {
  var elapsed = 0;

  // THIS stopwatch function is referenced later
  var stopwatch = function() {
    return elapsed;
  };

  var increase = function() {
    elapsed++;
  };
  // This setInterval will continue running and calling the increase function.
  // we do not maintain access to it.
  setInterval(increase, 1000);

  // THIS returns the stopwatch function reference earlier.  The only way
  // we can interact with the closure variables are through this function.
  return stopwatch;
};

var stopwatch1 = makeStopwatch();
// This runs the makeStopwatch function.  That function *RETURNS* the
// inner stopwatch function that I emphasized above.

console.log(stopwatch1());
// stopwatch1 is a reference to the inner stopwatch function.  We no longer
// have access to the elapsed variable or the function increase.  However
// the `setInterval` that is calling `increase` is still running.  So every
// 1000ms (1 second) we increment elapsed by 1.

So if were were to put all of the above code into the console, and then call console.log(stopwatch1()) sporadically, it will console.log the number of seconds since we created the stopwatch.

like image 53
ChadF Avatar answered Oct 27 '22 22:10

ChadF