Redefine Function Between Its Initialization And Invocation
Solution 1:
Setting the timeout to zero doesn't necessarily mean that the callback will be run immediately. Control immediately proceeds to the next line, where you return inner
. At this point in time it has not been redefined and f
points to the old inner
, which is why you are seeing "Initial".
Change your code to the following:
var inner = function() { console.log('Initial'); }
var outer = function() {
setTimeout(function() {
inner = function() { console.log('Redefined'); }
}, 0);
return inner;
}
outer();
setTimeout(function() {
inner();
}, 1000);
Now you'll see "Redefined", because we call outer
which will redefine inner
at some point in the future. When we then call inner()
within the timeout handler, it is pointing to the redefined version and so it will print "Redefined".
You might wonder why we couldn't just do this:
var inner = function() { console.log('Initial'); }
var outer = function() {
setTimeout(function() {
inner = function() { console.log('Redefined'); }
}, 0);
return inner;
}
outer();
setTimeout(inner, 1000);
But you'll get "Initial" here as well for the same reason; when setTimeout
is called inner
is still pointing to the original version.
Solution 2:
This because the value of inner
is set after the all of other JS is executed. That function is sent to other stack and is removed from the main
stack. Even if you set the timer to 0 ms; the setTimeout function will be executed when all other JS executed. Here's how your program is executed:
- Initializes
inner
andouter
. - Executes
outer
and initializesf
with the return value.
BUT how does outer()
gets executed? Here's how:
- Hits
setTimeout
Web API which has a function which should execute after 0 ms but it will be sent to event loop and will be executed later. The rest of the code will be executed. Hits
return
statement. It will access the value ofinner
. Now, remember your setTimeout function isn't executed yet. So, the function will move upto the prototype chain and findinner
. Asinner
was defined inGlobal
context. That value will be returned.Finally, the
outer()
returns a function tof
which is executed by anothersetTimeout
. The function insetTimeout
will also be sent to event loop.
Now, event loop has 2 functions to be called! One of them will reset the value of inner and the other will alert "Initial" but, the value of inner
will be changed instantly. The alert will be displayed after 1s as defined.
Post a Comment for "Redefine Function Between Its Initialization And Invocation"