JavaScript variable declaration elevation (hoisting)
JavaScript's variable declarations have a hoisting mechanism, and the JavaScript engine, when executed, promotes the declaration of all variables to the front of the current scope .
Look at a piece of code first
12345 |
var v = "hello" ; ( function (){ console.log(v); var v = "world" ; })(); |
What is the result of this code running?
The answer is: undefined
This code illustrates two questions,
First, the variable v in the function scope obscures the upper-scope variable v. Code to do less change
12345 |
var v = "hello" ; if ( true ){ console.log(v); var v = "world" ; } |
The output is "hello", which means that JavaScript is not block-scoped . a function is the only structure in JavaScript that has its own scope.
Second, within the function scope, the declaration of the variable v is promoted. So the initial code is equivalent to:
123456 |
var v = "hello" ; ( function (){ var v; //declaration hoisting console.log(v); v = "world" ; })(); |
Declaration, definition, and initialization
The declaration declares the existence of a name, and the definition allocates storage space for that name, while initialization assigns the initial value to the storage space allocated by the name.
Use C + + to express these three concepts
123 |
extern int i; //这是声明,表明名字i在某处已经存在了 int i; //这是声明并定义名字i,为i分配存储空间 i = 0; //这是初始化名字i,为其赋初值为0 |
This is the case in JavaScript.
12 |
var v; //声明变量v v = "hello" ; //(定义并)初始化变量v |
Because JavaScript is a dynamic language, its variables do not have a fixed type, their storage size will vary with initialization and assignment, so the definition of its variable is not like the traditional static language, and its definition does not seem to matter.
Declaring elevation
Declarations within the current scope are promoted to the front of the scope, including declarations of variables and functions
123456 |
(
function
(){
var a =
"1"
;
var f =
function
(){};
var b =
"2"
;
var c =
"3"
;
})();
|
The declaration of the variable A,F,B,C is promoted to the front of the function scope, similar to the following:
1234567 |
( function () {    var A,F,B,C;    a = "1"    f = function () {};    b = "2"    c = "3" |
Note that function expressions are not promoted, which is also the difference between function expressions and function declarations. Look further at the difference between the two:
123456789 |
( function () { //var f1,function F2 () {};//hoisting, implicitly promoted declaration    f1 (); //REFERENCEERROR:F1 is not defined    f2 ();    var f1 = function () {};    function f2 () {} |
The function declaration F2 is promoted in the above code, so it is no problem to call F2 in front. Although the variable F1 is also promoted, the F1 promoted value is undefined, and its true initial value is given at execution to the function expression. So only the declaration is promoted.
Name resolution Order
In JavaScript, a name (name) enters the scope (scope) in four ways, with the following order of precedence:
1, language built-in: All scopes have this and arguments keywords
2, formal parameters: function parameters are valid in the scope of the function
3, Function declaration: Shape as function foo () {}
4, Variable declaration: shape as Var bar;
The precedence of a name declaration is shown above, meaning that if the name of a variable is the same as the name of the function, then the name of the function overrides the name of the variable, regardless of its order in the code. However, the initialization of a name is done in the order in which it is written in the code, and is not affected by the precedence above. Look at the code:
123456789 |
(
function
(){
var foo;
console.log(
typeof foo);
//function
function foo(){}
foo =
"foo"
;
console.log(
typeof foo);
//string
})();
|
If there is more than one variable with the same name in the form parameter, the last parameter with the same name overrides the other parameter with the same name, even though the last parameter with the same name is undefined.
There are exceptions to the first name resolution precedence, such as the ability to override the language's built-in name arguments.
Named function expressions
You can specify a name for a function expression like a function declaration, but this does not make the function expression a function declaration. The name of the named function expression does not enter the namespace and is not promoted.
12345 |
f(); //TypeError: f is not a function foo(); //ReferenceError: foo is not defined var f = function foo(){console.log( typeof foo);}; f(); //function foo(); //ReferenceError: foo is not defined |
The name of a named function expression is valid only within the scope of the function.
Transferred from: http://openwares.net/js/javascript_declaration_hoisting.html
JavaScript Variable declaration elevation