Immediately Invoked Function Expression use case:inadvertent sharing via closures [duplicate] - javascript

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 8 years ago.
var result=[];
for(var i=0;i<5;i++){
result.push(function () {return i});
}
console.log(result[1]()); //5 not 1
I think the result should be [0,1,2,3,4] and I don't understand why the value should be 5. How does it work? I am completely confused.

Because JavaScript does not have block scope, it has function scope. There is only one i variable, and it exists for the whole function. It is changed from 0, to 1, and so on, up to 5. All of the closures reference this same variable.
You can fix it by passing the value in to an immediately-invoked function that returns another function:
result.push((function (i) { return function() { return i; } }(i));
In this case you pass the value of i in to the outer function, which returns another function that returns the argument to this inner function, effectively capturing the value of the outer i at that particular moment.

Related

Don't understand a construct in a JS Decorator [duplicate]

This question already has answers here:
How do JavaScript closures work?
(86 answers)
Closed 3 years ago.
I was studying on JS Decorators and don't understand how the wrapper is able to access the inner functions argument. The snippet works, but I don't understand why the anonymous function 'function(val)' gets access to val, the argument of slow().
// https://codepen.io/lideebe/pen/VOjGvb
// simple function that gets wrapped
function slow(x){
return x * 3;
}
// the wrapper function
function cacheDecorator(func){
return function(val){ // How does this anonymous function get access to val?
return func(val)
}
}
// do the wrap
slow = cacheDecorator(slow);
// call the function
console.log(slow(2));
Output is 6 and that is correct.
It's because cacheDecorator returns a function which takes a parameter val, and when you call that returned function with the value 2, it just gets accessed like normal. So slow, after you reassign it, is:
slow = function(val) {
return val * 3;
}
So val is used as the parameter for the argument passed when the newly wrapped function is called.

How each call finds the variable outside a for loop which includes a inner function? [duplicate]

This question already has answers here:
Explanation of `let` and block scoping with for loops
(5 answers)
How do JavaScript closures work?
(86 answers)
Closed 5 years ago.
Regarding the let Declarations in loops in book Definitive JavaScript Developer guideline, the code:
var funcs = [];
for (let i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i);
});
}
funcs.forEach(function(func) {
func(); // outputs 0, then 1, then 2, up to 9
})
It says:
The let declaration creates a new variable i each time through the loop, so each function created inside the loop gets its own copy of it. Each copy of i has the value it was assigned at the beginning of the loop iterations in which it was created..
I want to know, when invoke the function func(), how and where it finds the i value for each element in array of funcs. All element in funcs are same
ƒ () {
console.log(i);
}
Could someone illustrate how each step happens when call the function in the above code? (I sort of understand that, if use var instead of let, the global variable i is what each call finds.)

Javascript -What happens if a variable and a function have the same name? [duplicate]

This question already has answers here:
Function and variable with the same name
(2 answers)
Closed 5 years ago.
Might be a kind of easy question, but I have a question on the issue of having the same name for a variable and a function.
If there's a variable,
var add = 1;
and a function,
function add(x,y) {return x+y;}
and there're two console.log,
console.log(add)
console.log(add(1,2))
I've expected those 2 console.log would work properly since add contains the Number and add() is classified as a Function, but the second one prints an error. So they aren't considered the same.
But the result says I'm wrong.
Can anyone explain what's going on in my code?
Variables and function definitions(not expressions) are hoisted to up, it means that wherever in scope you wrote your function or variable they will be moved to the start of the scope. First goes functions definitions then variables. So it means that functions will be overwritten by variables.
var add = 1;
function add(x,y) {return x+y;}
console.log(add);
The order doesn't matter. Later will be the variable and will overwrite
function add(x,y) {return x+y;}
var add = 1;
console.log(add);

what's the statement execution order of this JS closure ? [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 6 years ago.
I have known the key of closure is about scope. But I don't know the specific execution order of it.
A classical code from 《Professional JavaScript for Web Developers 3rd Edition》about closures.
function createFunctions(){
var result=new Array();
alert('haha');
for(var i=0;i<10;i++){
result[i]=function(){
alert(i);
return i;
};
}
return result;
}
var a=createFunctions();
To my surprise, 'haha' was alerted while none of 'i' were alerted.I was just assigning the function to variable a.Why the statement "alert('haha')" was alerted while the cycle wasn' t executed?
when I add the below code,
var a=createFunctions();
alert(a[2]);
why it alerted like this
function (){
return i;
}
not like
function (){
return 2;
}
Furthermore when I add the below code, what will being the order of statements executed especially the statements in the cycle.
var a=createFunctions();
alert(a[2]());
When you call
var a=createFunctions()
alert('haha') is executed immediately, and an array of 10 functions is created and assigned to the variable 'a', each function alerting 'i' and returning it.
However, by the time any of those functions is called (provided you call them after creating them) the value of i is '10' (the loop termination value). So every time you call one of the functions, with
alert(a[x]())
( with any value of x = 0 thru 9 )
it will alert(10) as the function executes and alert(10) again when it returns.
Why the statement "alert('haha')" was alerted
Because it was an alert statement in the function you called.
while the cycle wasn' t executed
The cycle was executed. The cycle just creates some functions and assigns them to positions in an array. You never call any of those functions.
and when I add the below code, what will being the order of statements executed
It depends where you add it.

Passing arguments to javascript function [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Javascript closure inside loops - simple practical example
javascript variable scope/closure in loop after timeout
Can you please explain step by step why the results are different?
Snippet A (alerts 10)
for(var i=0; i<10; i++) if(i==3) setTimeout(function() {alert(i);}, 100);
Snippet B (alerts 3)
for(var i=0; i<10; i++) if(i==3) setTimeout((function(p) {
return function() {alert(p);}
} )(i), 100);
A variable's scope is either the global scope (window in a browser) or a function.
In the first case i is defined in the scope containing the for loop. This is why it still changes until the end of the loop before the callback given to setTimeout is executed.
In the second case, the intermediate function contains and keeps another variable, p. Note that this would have worked without the test, as this would have been a different closure for each setTimeout.

Categories