In Javascript, can I use a variable before it is declared?
Asked Answered
S

5

33

I have been wondering for a while if I can use a variable in JS before it is defined, such as the following:

var country = "USA";
switch (country) {
    case "USA":
        country = i;
    case "blach":
        //not finished yet
}
/*
  put a whole
  bunch more code here
*/
var i = 10;

Is this valid? Is it allowed? And if so, what is the technical term for it?

Steep answered 26/11, 2013 at 15:12 Comment(1)
Sorry, but I felt that this question does not "show enough research effort". Variable scope is fundamental programming knowledge. Simply running the code in question should have proved that is was allowed. The question is probably "what is the technical term for using variables before they are declared". Feel free to edit the question and the downvote might go away. I will point out that even this JavaScript question has no mention of hoisting.Lumbye
I
37

This is a technique used by the JavaScript engine called hoisting. The parser will read through the entire function before running it, and any variable declarations (i.e. using the var keyword) will be executed as if they were at the top of the containing scope. So your code behaves like:

var country;
var i;

country = "USA";
switch (country) {
case "USA":
    country = i;
case "blach":
    //not finished yet
}

i = 10;

So, i is declared throughout the entire scope, but its value is undefined until the i = 10 statement runs.

In ECMAScript terms, when a function is invoked, the function's new lexical scope builds its VariableEnvironment before any of the function's code runs. In ECMAScript 10.5, step 8:

8. For each VariableDeclaration... d in code, in source text order do

a. Let dn be the Identifier in d.

...

i. Call env’s CreateMutableBinding concrete method passing dn and configurableBindings as the arguments.

ii. Call env’s SetMutableBinding concrete method passing dn, undefined, and strict as the arguments.

This is quite a mouthful, but basically it says:

Before you run a function, look through the function's source code for declarations like var [identifierName].

For each declaration you find, create a new variable in the function's scope with the name [identifierName] used in the declaration and then set its value to undefined

Illuminometer answered 26/11, 2013 at 15:15 Comment(1)
Nice that you added a reference to 10.5.8 +1 for that :)Facsimile
E
11

It's called variable hoisting, and it's a good concept to understand as it can occasionally create bugs that are hard to track down.

For example:

var stuff = 'stuff';
function() {
 console.log(stuff); //outputs 'undefined'
 var stuff = 'other stuff';
 console.log(stuff); //outputs 'other stuff'
}

The first console.log outputs undefined because the var stuff in the function was hoisted to the top of the function.

//theoretical compiled output
var stuff = 'stuff';
function() {
 var stuff; //has not been defined
 console.log(stuff);
 stuff = 'other stuff'; //defined here
 console.log(stuff);
}

Without knowledge of variable hoisting, this result may be confusing.

For this reason, if you look at professionally developed JavaScript code, typically you'll see all variables in a function are declared at the top.

Emulation answered 26/11, 2013 at 15:14 Comment(0)
F
3

Yes. In JavaScript, variables are hoisted

A variable statement declares variables that are created as defined in 10.5. Variables are initialised to undefined when created. A variable with an Initialiser is assigned the value of its AssignmentExpression when the VariableStatement is executed, not when the variable is created.ES5 §12.2
Where 10.5 step 8 is the part of interest

Facsimile answered 26/11, 2013 at 15:13 Comment(0)
D
2

The guys answers are correct. for your example however it is worth noting that country is undefined. as aspillers has mentioned your code behaves as below

var country;
var i;

country = "USA";

switch (country) {
case "USA":
    country = i;
case "blach":
    //not finished yet
}

i = 10;
alert(country) //undefined;

but when your case statement ran for "USA", i was undefined so this was assigned to country. try it here in this fiddle.

I guess that you just need to be aware that although the variable declarations are hoisted, the value assignments aren't.

Dartmouth answered 26/11, 2013 at 15:18 Comment(2)
I am new to JS so I do not know much. Pardon, but what I understood is that hoisting means that no matter where are the var may be in the current scope; it will be allocated a memory before the execution is started. then why the variable is undefined?Benedictbenedicta
@VikasBansal - Only the reference is hoisted. the assignment of a value is not hoisted. So in the example country = i in the switch statement is just assigning undefined to country as the value of i is assigned right at the endDartmouth
E
1

Yes, you can use a variable before declaring it. It's called hoisting in JavaScript. One thing to keep in mind though is that only a variable's declaration is hoisted, not its initialization. It means that you'll not able to use the value of the variable which you'll assign later in the code. For example,

console.log(myVar); //undefined
myVar = 10;
var myVar;

So you'll not get the error (myVar is not defined) even when you're using myVar before declaring it. But the console logged value of myVar will be undefined. At the starting of code execution, variable was declared, but its assignment was not. So the JS engine would see the above code block as

var myVar;
console.log(myVar); //undefined
myVar = 10;
var myVar;

It will put the declaration for all the variables used in the file at the top of the code.

Eluvium answered 23/1, 2023 at 8:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.