This question already has answers here:
What is the difference between "let" and "var"?
(39 answers)
Closed 4 years ago.
I noticed a bug in my code a couple days ago and have no idea why it's happening. It seems a variable defined in a lower scope is somehow jumping up to a higher one. Anyone know what's happening here? Dumbed down code:
console.log(a)
for(var k = 0; k < 5; k++)
var a = 5
console.log(a)
The first console log always prints undefined
But the second console log always prints 5?
Shouldn't variable a only exist in the for loop's scope and be cleared from memory once the for loop is done?
Variables defined with var are "function scoped", so they are accessible anywhere in the function. let and const however have "block scoping", they will behave like you expect:
{
let a = 1;
var b = 2;
}
console.log(a, b); // not defined, 2
Related
This question already has answers here:
Explanation of `let` and block scoping with for loops
(5 answers)
JavaScript closure inside loops – simple practical example
(44 answers)
let keyword in the for loop
(3 answers)
JavaScript: Understanding let scope inside for loop [duplicate]
(3 answers)
Closed 6 months ago.
This question is inspired by a very famous trick interview question for javascript closures, however I am more interested into another aspect of it. The code goes as follows:
let i
for (i = 0; i < 3; i++) {
setTimeout(function log() {
console.log(i); // What is logged?
}, 1000);
}
The answer is 3 3 3, and (I think) I know the explanation, each callback function can access the same i variable, by the time they are executed its value is 3.
When we write let inside for loop like this:
for (let i = 0; i < 3; i++) {
setTimeout(function log() {
console.log(i); // What is logged?
}, 1000);
}
Now we get 0 1 2. Ok, here the explanation is that when declared this way, i is scoped to this loop, not available outside, and each iteration has its copy of i.
The part that bugs me: it does not seem to be a different variable in each step. If we change i in a first step, it will be changed for other steps.
for (let i = 0; i < 3; i++) {
setTimeout(function log() {
console.log(i); // What is logged?
}, 1000);
if (i === 0) i ++
}
The result now is 1 2, skipped one step.
So I see two possible explanations for this, but I cannot confirm this anywhere.
Closures work differently for block-scoped and function or global scoped variable
After each step of the loop, the current state of the variable declared in a loop is copied to a new variable for the next step of the loop
???
Note: Please let's not focus on why values are 3 3 3 instead of 2 2 2, let's not go into event loop with setTimeout etc. unless relevant to the answer. I feel like closures and variable scopes will be most relevant here.
This question already has answers here:
How JS hoisting works within functions?
(4 answers)
Why a variable defined global is undefined? [duplicate]
(3 answers)
Closed last year.
My first guess is that the following code has the output of 10 and 100. However, after running the code I get undefined and 100 and I don't understand why the function doesn't see the first declaration of x..
var x = 10;
function f() {
console.log(x);
var x = 100;
console.log(x);
}
f();
This question already has answers here:
setTimeout in for-loop does not print consecutive values [duplicate]
(10 answers)
JavaScript closure inside loops – simple practical example
(44 answers)
What is the difference between "let" and "var"?
(39 answers)
Closed 1 year ago.
I am reading about closures, and I found these small exercises that I solved by chance, but I don't understand why they work.
The exercise is :
for (var i = 0; i < 3; i++) {
setTimeout(function log() {
console.log(i); // What is logged?
}, 1000);
}
I get that 3 will be printed 3 times because the value captured by log() when the for() ends.
Additionally, it was asked how to fix it for the console to print 0,1,2, and I found (by chance, to be honest), that it works by doing :
for ( let i =0 ...
But I guess because Let is block scoped, but i don't really know how to explain it in simple words.
The variables defined with let are blocked scope which means once you go out of the bracket it loses its value and if you try to access it will throw you an error. So, when the for is running the, i present in the console.log() will store the value for it like 0,1,etc.
whereas in the var part the var will be stored in memory and when the timeout is about to expire it will access the variable i in the memory and print whatever is there for that variable at that time.
This question already has answers here:
What is the temporal dead zone?
(3 answers)
Closed 3 years ago.
the expected output as far as I understand must be :
10
22
let y = 10;
{
console.log(y); // this line gives refrence error
let y = 22;
console.log(y);
}
{
console.log(this.y); // this line gives refrence error
let y = 22;
console.log(y);
}
You are trying to call a variable that is not declared yet. Thats why you're getting this error. Your first console.log is not looking at the global scope ,it's looking at the block scope. And at the time you're calling it, it's not defined yet. A " var" would've returned undefined. let and const return this error. I hope it's clear.
You can test this yourself using 'this'. as you can see this.y is undefined.
This question already has answers here:
Global JavaScript Variable Scope: Why doesn't this work?
(5 answers)
Javascript function scoping and hoisting
(18 answers)
Closed 8 years ago.
I need to understand how the JavaScript engines in browsers read functions. Consider the code below:
var g = 5;
alert(g); //alerts 5
function haha() {
alert(g); // alerts NOTHING. Why is this? Why not alert 5? var g = 45 hasn't yet occurred
var g = 45;
alert(g); // alerts 45
};
haha();
alert(g); // alerts 5. Because g = 45 is a local variable.
Fiddle
The effect you're seeing where alert(g) in the haha function alerts undefined is from variable hoisting.
The haha function is actually executed as:
function haha() {
var g;
alert(g);
g = 45;
alert(g);
}
This is because variable and function definitions are hoisted to the top of their scope in JavaScript.
The effect can lead to some rather unintuitive behavior, such as what you're seeing. The simple solution is to always declare your variables and functions before any executing code so that the written code matches what's being executed.