Scope in Javascript: Why is the answer 10, not 20? [duplicate] - javascript

This question already has answers here:
What is the scope of variables in JavaScript?
(27 answers)
Closed 6 years ago.
I'm learning about scope in JS. I was just thinking that I'm getting the hang of it, when I came across this example:
var x = 20;
for (x = 0; x < 10; x++) {
}
// returns 10
console.log(x);
Why 10? I would have expected 20 as an answer.

When you start your for loop, you are currently writing for (x = 0). This is overwriting the var x = 20 statement, so now x = 0. The loop continues to run as you would expect.
When you use the var keyword, you are creating a new variable in that current scope. Because you are not initializing your for loop with the var keyword, basically, JavaScript looks for an existing variable called x. It finds the one you created with var x = 20 and will overwrite the reference, so now x = 0.

It returned 10 because for loop changed it by incrementing. You didn't create new variable, so Javascript automatically overwrote already existing. This is because you created for loop, which has that variable as an initial expression. It happens when you want refer to a variable, that doesn't exist in lexical environment, syntax parser take it from outside. It means in this case, that from global object where you declared variable x. Then your loop changed that variable to 10.
I hope, I explained to you what happened. Please be understanding for me, I'm new here.

In JavaScript (EMCA-Script < 6) you can only create scopes with functions. Any other language construct won't create scope:
for(var i = 0; i < 10; i++) {}
// Logs 10 because "i" in the for loop doesn't create
// a block scope so "i" is available after the whole loop
console.log(i);
Since you've already declared an x before your for loop, and the whole loop uses x from 0 to 10, because for block won't create a scope, it's absolutely right that you get 10.
Scopes with functions:
function doStuff() {
// Inner scope
var a = 10;
}
// Outer scope
var a = 20;

x is 20 at start and then you change its value in a for cycle. The cycle changes its value to 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10. At the end you have 10 as value, so the result you experienced is in fact the expected result.

Related

Scope of variable defined in loop initialization in Javascript? [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
let keyword in the for loop
(3 answers)
Closed 2 years ago.
Why is the output of the following code :
let nodes = [];
for (let i = 0; i < 5; ++i) {
nodes[i] = () => i;
}
for (let node of nodes) {
console.log(node());
}
is 0 1 2 3 4, while the output of the following code :
let nodes = [];
let i;
for (i = 0; i < 5; ++i) {
nodes[i] = () => i;
}
for (let node of nodes) {
console.log(node());
}
is 5 5 5 5 5?
let variables are scoped the to the block you use it in.
If you use let outside the for block, then you create one variable shared by each function you create (and you change the value of that variable each time you go around the loop).
If you use let inside it, you create a new variable each time you go around the loop, so each function has its own variable with a value that you aren't changing.
How do closure and environment context come into play in this?
They don't really. It's just a matter of if each function closed over the same i or a different i … and you aren't using this.
The type of function you use is irrelevent. You'd get the same effect with a function expression.
Variables declared by let have their scope in the block for which they are defined, as well as in any contained sub-blocks.
In your first code, variable i is declared as local variable during iteration. But in the second code, i is declared as a global variable. So that it prints 5,5,5,5,5
Please refer this link:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

Why do var and let produce different outputs in closures? [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
What is the difference between "let" and "var"?
(39 answers)
Closed 5 years ago.
Consider these 2 snippets:
With let:
for(let i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 100)
}
With var:
for(var i = 0; i < 10; i++) { //HERE
setTimeout(function() {
console.log(i);
}, 100)
}
From my understanding, let only affects the scoping of the variables, so why are the outputs of the 2 loops should be same, so why does let print 0-9 and var prints 10 10 times?
Because you have a timeout in your loop, none of your logs are being called until the entire loop is finished.
After the loop is finished, the value of i is 10 if you use var.
But let is block scoped, meaning it's the same value anywhere in the loop, even in an async function like setTimeout (unless you manually change it inside the loop) - because the loop creates a new scope on each iteration, it's almost like each iteration creates a new "instance" of the i variable when you use let, whereas using var each loop is using the same instance of the i variable.

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.)

`var` and `let` behaviour in arrow functions [duplicate]

This question already has answers here:
What is the difference between "let" and "var"?
(39 answers)
Closed 5 years ago.
Why i behaves differently in arrow functions? Is it because var x is being reassigned while let x is being created new for each iteration?
//prints 55555
for(var x = 0; x < 5;x++){
setTimeout(()=>console.log(x),0);
}
//prints 01234
for(let x = 0;x < 5;x++){
setTimeout(()=>console.log(x),0);
}
It has nothing to do with arrow functions. let is block level scope, so each time you enter the body of the loop, you get a new variable.
In your case, the timer function prints differently, because of the closure being created around x.
var provides one variable that all iterations of the loop (and therefore, all timer callbacks) share, hence you get the last value of the variable shared by each timer callback. Remember, the timer callbacks won’t run until your loop is finished and, at that time, x has been incremented to 5.
let gives each timer callback it’s own value because of the block scope. So, even though the timer callbacks don’t run until the loop is finished, each callback has a closure around a differently scoped variable.
let in the loop can re-binds it to each iteration of the loop, making
sure to re-assign it the value from the end of the previous loop
iteration, so it can be used to avoid issue with closures.
Read more here: http://www.jstips.co/en/javascript/keyword-var-vs-let/

Understanding JavaScript scopes [duplicate]

This question already has answers here:
What is the scope of variables in JavaScript?
(27 answers)
Closed 5 years ago.
I'm trying to understand how scopes work in JS. Can you tell me if I correct with understanding of this chunk of code:
for(var i = 0; i<5; i++){
setTimeout(function timeoutHandler() {
var i = i;
console.log(i); //undefined
})
}
console.log prints undefined 5 times. So as I understand, when timeoutHandler is executed, it has its own local scope with own i variable. So is that correct that during timeoutHandler execution, the interpreter asks for i variable, finds it declared in local scope and uses this declared variable for assignment? This explains why it is undefined, but I'm not sure I'm fully correct.
Thanks
UPD
I don't need this code to work properly, I just want to understand why it behaves like that in this case
Trying to make sense of it by this example:
for(var i = 0; i<5; i++){
//create a self executing function
(function(iValue){
//in this scope iValue has the i from the loop
setTimeout(function() {
console.log(iValue); //will print the correct i
})
})(i); //pass i in it's current context to the function
}
Or easier with ES6:
Use let instead of var.
Since let is scoped within the block (each run of the loop is it's own block) it will not get another value inside the setTimeout.
for(let i = 0; i<5; i++){
setTimeout(function() {
console.log(i); //will print the correct i
})
}

Categories