Skip to content Skip to sidebar Skip to footer

Redefine Function Between Its Initialization And Invocation

Why does this alert Initial instead of Redefined: var inner = function() { alert('Initial'); } var outer = function() { setTimeout(function() { inner = function() { ale

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:

  1. Initializes inner and outer.
  2. Executes outer and initializes f with the return value.

BUT how does outer() gets executed? Here's how:

  1. 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.
  2. Hits return statement. It will access the value of inner. Now, remember your setTimeout function isn't executed yet. So, the function will move upto the prototype chain and find inner. As inner was defined in Global context. That value will be returned.

  3. Finally, the outer() returns a function to f which is executed by another setTimeout. The function in setTimeout 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"