Monday, 8 January 2018

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

itemprop="text">

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?



Answer




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.



No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print ...