7
for(var i=0;i<5;i++){}
alert(i);

in javascript this will get us 5 other languages like C++, java, c# .... will simply give an error that the i variable isn't defined in the context.

So why the for loop counter doesn't get destroyed after exiting the loop in javascript?

Modar
  • 85
  • 6
  • 1
    possible duplicate of [variable hoisting](http://stackoverflow.com/questions/3725546/variable-hoisting) – Ryan Cavanaugh Jul 04 '13 at 17:13
  • all you need to know http://stackoverflow.com/questions/500431/javascript-variable-scope – Manoj Purohit Jul 04 '13 at 17:14
  • read this: [Javascript's declaration of variables in a function scope, meaning that **variables declared in a function are available anywhere in that function, even before they are assigned a value.**](http://thecomputersarewinning.com/post/a-dangerous-example-of-javascript-hoisting/) – Grijesh Chauhan Jul 04 '13 at 17:27
  • [**Variable scope:**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Values,_variables,_and_literals?redirectlocale=en-US&redirectslug=JavaScript/Guide/Values,_variables,_and_literals#Variable_Scope) – Grijesh Chauhan Jul 04 '13 at 20:14

3 Answers3

11

This is because the JavaScript engine will move ("hoist") the variable decalaration to the top of the function no matter where it is declared inside the function1. JavaScript does not have block scope.

{
//Some code
    for(var i=0;i<5;i++){}
    alert(i);
//Some code
}

Is equivalent to:

{
  var i;
 //.. some code
 for(i=0;i<5;i++){}
    alert(i);
}

1 Unless it's the exception being caught with a catch clause; that variable is scoped to catch block.

Update

For defining block scope variables ecmascript 6 specs (javascript 1.7) introduces let. Currently this will work only in latest version of FireFox browser and in consensus stage.

<script type="application/javascript;version=1.7">
     //Some code

        for (let i = 0; i < 10; i++) {

            alert(i); // 1, 2, 3, 4 ... 9
        }

        alert(i); // Here you will get an error here saying ReferenceError: i is not defined.
    }
</script>

Fiddle

Community
  • 1
  • 1
PSL
  • 123,204
  • 21
  • 253
  • 243
  • @user1525337 You are welcome. Probably read this about scopes - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheet – PSL Jul 04 '13 at 17:22
  • 1
    + ok that is the reason *`JavaScript does not have block statement scope;`* Got it now, I didn't read your answer first but its very helpful answer. – Grijesh Chauhan Jul 04 '13 at 18:18
  • Maybe you should revise your first sentence because it makes it seem like this would work if it weren't for hoisting. – holographic-principle Jul 17 '13 at 16:46
3

Javascript only creates scopes for functions, with and catch blocks (with functions creating a scope for var statement), so equivalent to Java (and not working) would be:

(function(){
    for(var i=0;i<5;i++){}
})();
alert(i);
Esailija
  • 138,174
  • 23
  • 272
  • 326
  • 1
    No, it also creates scopes for `catch` clauses. –  Jul 04 '13 at 17:18
  • @torazaburo true, easy to forget :) – Esailija Jul 04 '13 at 17:19
  • 1
    @torazaburo It creates a scope for the variable containing the catch exception (defined in the catch clause), but it does *not* create a general scope for variables defined in the catch *block*, correct? ([This seems to be what I'm experiencing here.](http://jsfiddle.net/jeremy/NFufk/)) – Jeremy Jul 04 '13 at 17:31
  • I believe this answer is wrong. [Neither with blocks nor catch blocks appear to create a new block scope](http://jsfiddle.net/jeremy/NFufk/1/). – Jeremy Jul 04 '13 at 20:28
  • You are right, variables defined within a catch clause are hoisted to the top of the function like any others, it is the caught variable that is in its own little context. Sorry for any confusion. I should have said "No, it also creates a scope for the variable caught in a `catch` clause." –  Jul 04 '13 at 20:43
  • @JeremyBanks that's not what I meant by it. I will clarify. – Esailija Jul 04 '13 at 21:57
  • And, a new scope is created for the function name in a function expression. –  Jul 06 '13 at 12:50
  • @torazaburo no, why would that create scope by itself? – Esailija Jul 06 '13 at 13:01
  • @Esailija, I mean, in a case such as `x=(function factorial(n){return n ? factorial(n-1) : 1;})(77)`. a separate scope is created to include the name "factorial" in the function expression. See http://kangax.github.io/nfe/, which says "An important detail to remember is that this name is only available in the scope of a newly-defined function; specs mandate that an identifier should not be available to an enclosing scope". –  Jul 06 '13 at 18:46
  • @torazaburo Yes but that scope is the same as the scope that needed to be created for the function anyway – Esailija Jul 06 '13 at 20:58
  • Actually, not. Consider the following: `(function f(f){alert(f);})`. A scope is created for the function name, and then another internal scope for the function including its argument. So the alert will show the argument, not the function. Same holds for `(function f(){var f=1;})`. In either case, a scope is created for the function name (necessary so it is not visible outside), and then another scope for the function itself is created, which contains the arguments and variables, and is what allows them to override the function name in the enclosing scope. –  Jul 08 '13 at 03:01
  • @torazaburo None of those mean that another scope would be required. The function name is only available to the function scope and observably works just the same as any other variable inside the function scope. None of the variables are visible to outside in the first place: `(function(){var x = 3;})() //x is not visible here in the enclosing scope` so how is function name special? Naming the function there would have exactly the same effect as `(function(){var functionName = arguments.callee;})();` – Esailija Jul 08 '13 at 09:52
0

Variables in Javascript are subjected to var hoisting where the variable becomes declared above the block by the javascript engine.

See The Mozilla Javascript documents on var for an example of how this will work.

Robert H
  • 11,520
  • 18
  • 68
  • 110