Hoisting mechanism
The JavaScript variable declaration has a hoisting mechanism that, when executed, promotes the declaration of all variables to the front of the current scope.
Read a piece of code first
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 covers the upper scope variable v. Code to make less changes
var v = "Hello";
if (true) {
console.log (v);
var v = "World";
}
The output is "Hello", which indicates that JavaScript is not a block-level scope. A function is the only structure in JavaScript that has its own scope.
Second, in the function scope, the declaration of variable v is promoted. So the initial code is equivalent to:
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 assigns storage space to the name, while initialization assigns the initial value to the storage space allocated by the name.
Use C + + to express these three concepts
extern int i;//This is a declaration indicating that the name I already exists somewhere
int i;//This is declaring and defining name I, allocating storage space for I
i = 0;//This is the initialization name I, which is assigned an initial value of 0
That's the way it is in JavaScript.
var v;//declaration Variable V
v = "Hello";//(define and) Initialize variable V
Because JavaScript is a dynamic language, its variables do not have a fixed type, and their storage size varies with initialization and assignment, so the definition of the variable is not the same as the traditional static language, and its definition does not matter.
Claim elevation
Declarations within the current scope are elevated to the front of the scope, including declarations of variables and functions
(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:
(function () {
var a,f,b,c;
A = "1";
f = function () {};
b = "2";
c = "3";
}) ();
Note that the function expression is not elevated, which is also the difference between a function expression and a function declaration. Look further at the difference between the two:
(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 before. Although the variable F1 is also promoted, the F1 value after ascension is undefined, and its true initial value is given at the execution of the function expression. So only the declaration is promoted.
Name resolution Order
A first name (name) in JavaScript enters 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 in the scope of the function is valid
3. function declaration: Shape like function foo () {}
4, variable declaration: like Var bar;
The precedence of a name declaration is shown above, that is, 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. But the names are initialized in the order in which they are written in the code, and are not affected by the above priority. Look at the code:
(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 formal argument, the last parameter with the same name overrides other parameters with the same name, even if the last parameter with the same name is not defined.
There are exceptions to the above name resolution precedence, such as the arguments name that can be overridden in a language.
named function expression
You can specify a name for a function expression like a function declaration, but that does not make the function expression a function declaration. The name of a named function expression does not enter the namespace and is not promoted.
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 only valid within the scope of the function.
Take another look at the following example:
var myval = "My global var";
(function () {
console.log (myval);//log "My global var"
}) ();
The above code will obviously output "my global var", but if we modify the above code slightly as follows:
var myval = "My global var";
(function () {
console.log (myval);//log "undefined"
var myval = "My local var";
}) ();
The result of the execution is the output of a undefined, and the reason for this result is that the declaration of the variable is promoted, and the above code is equivalent to the following:
var myval = "My global var";
(function () {
var myval;
Console.log (Myval); Log "undefined"
myval = "my local var";
}) ();
What is promoted is only the declaration portion of the variable and is not initialized immediately, so output undefined.
However, this mechanism of ascension is not only manifested in ordinary variables but also in functions. For example, the following code cannot be executed correctly:
(function () {
fun ();//uncaught typeerror:undefined is not a function
var fun = function () {
Console.log ("H Ello! ");
}
) ();
Because it is equivalent to:
(function () {
var fun;
Fun (); Uncaught typeerror:undefined is not a function
fun = function () {
console.log ("hello!");
}
) ();
An error occurs because the declaration of the function is also promoted without immediate initialization.
Of course, this way of defining a function is called a "function expression", there will be a lifting mechanism, if this is the following "function declaration" way, there is no lifting mechanism of the problem:
(function () {
fun ();
function Fun () {
console.log ("hello!");//Log "hello!"
}
) ();
This is also the main difference between a function declaration and a function expression.