1

console.log(i);
 for(var i=0;i<2;i++){
 console.log(i);
 }

This shows some unexpected output in browser. Can anyone please explain this? The output is:

Output

Its actually quite different on different console's. The mozilla documentation says this:

// myVarVariable is visible out here

for (var myVarVariable = 0; myVarVariable < 5; myVarVariable++) {
// myVarVariable is visible to the whole function }

// myVarVariable is visible out here

vsemozhebuty
13.9k1 gold badge29 silver badges28 bronze badges
asked Feb 1, 2019 at 16:19
14
  • 4
    What exactly is the "unexpected" part? Commented Feb 1, 2019 at 16:20
  • 1
    What is the question? It seems to be behaving exactly as I expect - you get undefined logged, then 0 then 1. What should happen instead? Commented Feb 1, 2019 at 16:21
  • 2
    Possible duplicate of JavaScript loop variable scope - Hmm. This may actually be dated. let seems to counter this answer, but for the current implementation OP is using, it stands true. Commented Feb 1, 2019 at 16:21
  • 1
    @RaghavMaheshwari i is available before the for loop. The value assignment isn't. The documentation is correct - it covers the visibility of the variable, not assignments. Commented Feb 1, 2019 at 16:27
  • 1
    I get undefined, 1, 0. I copy pasted your entire snippet from here as a single code that was run. Commented Feb 1, 2019 at 16:33

5 Answers 5

2

This is due to hoisting. In javascript the variable declared with var shows hoisting. Hoisting is process in which all the declarations of variables are brought to the top of of the scope on java script. But note they are not assigned the value which is assigned below in code. let and const doesnot show this behaviour

console.log(x);
var x = 4;
console.log(y)
let y = 4

answered Feb 1, 2019 at 16:23
Sign up to request clarification or add additional context in comments.

Comments

2

There's nothing unexpected in your code, it is behaving as it should.

console.log(i);

This log statement prints undefined because of a concept known as hoisting in javascript. When you define variables using var keyword, they are moved/hoisted to the top of the functional/local scope when javascript runs.

Now you might ask that if variable declaration is moved/hoisted to the top of the functional/local scope then why does logging i prints undefined? That's because only variable declarations are hoisted to the top, not the value of the variable. So when you log i before the loop, it gives you undefined because Javascript recognizes that variable i exists in this scope but isn't given a value yet.

Inside for loop is where variable i is initialized to value 0 and then loop executes twice and gives you 0 and 1.

Now you can also access variable i after the for loop and that is because of functional scope of var. What this means is that variables defined with keyword var are available globally if not defined in any function.

If you don't want this behavior, use let instead of var. let keyword provides block level scope which means that variables defined using let keyword are only available in the block (between curly braces) in which they are defined.

answered Feb 1, 2019 at 16:36

1 Comment

Thank you guys! It's all clear now. Was a very silly confusion for me.
1

Declare the variable as let and that won't happen. Also check this

answered Feb 1, 2019 at 16:22

5 Comments

That's fine but the code doesn't go in sync with the official documentation on mozilla website.
@RaghavMaheshwari how is it not in sync? The behaviour is as per the documentation you quoted - the first console.log(i) works because i is visible there which the documentation also says.
@RaghavMaheshwari Mozilla does not own any "official" documentation as they are not owners of the standards. Ecma International owns the EcmaScript/JavaScript standards and the W3C owns other Web standards. While not true in this case, it is entirely possible for them to have incorrect information on their website.
@DavidCrane you'd get hoisting even if you copy/paste the code block into the console (as opposed to pasting line by line). It's not only in the scope of functions. Moreover, it works in the global scope, which is why we'd be able to use a lot of stuff to begin with, thanks to hoisting function declarations.
@skyline3000 the website in question is MDN - the Mozilla Developers Network. It's not actually the property of Mozilla, it's a public wiki. The information there is regarded as very high quality and around SO is accepted on-par with official documentation. And no - the information in this instance is not wrong - the part quoted in the OP is very precisely correct. It's misunderstanding what it means. OP seems to expect a line of var i = 0 to set i to zero and you to see this value before reaching that line. The docs never claim this is the case.
1

Due to variable hoisting, var declarations are physically moved to the top of their execution context's scope (in this case the global scope). Thus, your code is the same as:

var i;
console.log(i);
for(i=0;i<2;i++){
 console.log(i);
}

answered Feb 1, 2019 at 16:31

Comments

0

In javascript inside loops use ler in place of var... then you can even use same name for variable and receive different results. Example below:

var x = 1;
 if (true) {
 var x = 2; // same variable
 console.log(x); // 2
 }
 console.log(x); // 2
 }
 function letTest() {
 let x = 1;
 if (true) {
 let x = 2; // different variable
 console.log(x); // 2
 }
 console.log(x); // 1
 }
answered Feb 1, 2019 at 17:14

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.