First of all, the title of the article "variable promotion" noun is the same as the flow, "variable promotion" to "identifier promotion" more accurate. Because variables generally refer to identifiers declared using Var, there is also an elevation (hoisting) for identifiers using function declarations in JS.
JS exists variable promotion (hoisting), this design is actually inferior, it allows the variable can not be declared to be accessible , or declared after use in the previous . Novice for this is very confusing, and even many use JS many years veteran also more confused. But after ES6 joins the Let/const, the variable hoisting does not exist.
One, the variable is not declared, directly use
function test () { alert (notdefined);} Test (); // ?
The error is natural.
Two. Variable declaration at the end
function test () { alert (declaredbutnotassigned);//undefined var declaredbutnotassigned;} Test ();
Output undefined, the result is better than the previous example, no error, code can run, but the variable value may not be expected by the programmer.
Third, the variable declaration at the end, while assigning values to the variable
function test () { alert (declaredandassigned);//undefined var declaredandassigned = 1;} Test ();
The result is the same as two, which is obvious and does not output 1 because it is assigned.
Two or three has a variable elevation (hoisting), simple definition
Variable elevation (hoisting): In the specified scope, the variable is declared in code order, but the accessibility of the run-time variable is elevated to the top of the current scope, with a value of undefined and no availability .
The code order and the order of Operation are emphasized here because most of the time the code we write is executed sequentially, i.e. the code order and the order of operation are consistent. Like a programmer with C language experience.
#include <stdio.h>int main () {int x = 1;printf ("%d,", x); 1}
Two lines of code, first declare the integer type x, and then output. The code order is consistent with the order in which it runs, that is, normal operation.
If the order in turn
#include <stdio.h>int main () {printf ("%d,", x); Errorint x = 1;}
At this point, the compilation will not pass. But JS can be so, see two or three.
Therefore, programmers with C language experience are well aware that variables need to be declared before they are used, otherwise they will be error-- And to the JS, there are variables to promote the phenomenon, can be used after the declaration , C experience with JS in the confusion will appear.
Four, the function expression also exists the variable promotion
function test () { alert (func);//undefined var func = function () {};} Test ();
However, if you want to use this func, it is not possible
function test () { alert (func);//undefined func ();//Report Exception var func = function () {};} Test ();
The result of Func is undefined, and calling Func will report an exception. Accessibility and usability are mentioned in the definition above for the following statements.
Accessibility: Alert (func), output undefined, can run, can access Func.
Availability: Func (), reported exception, unable to call Func Normally, indicates no availability.
Two, three or four is the use of Var declared variables, JS function declaration will also exist Ascension (hoisting), but this "variable" is a special, it is a function type (can be used as functions, methods or constructors). Its name (identifier) is also promoted to the top of the current scope.
The name of the function declaration is also promoted to the top of the current scope
function test () { alert (F1);//function F1 ();//"called" function F1 () { alert (' called ');} } Test ();
We see that the declaration F1 at the bottom of the code, F1 is used before, alert (F1) and F1 () are executed normally, indicating accessibility and availability .
As I said earlier, the variable promotion (hoisting) is useless, it belongs to the poor design of the language, the good habit is "first declaration after use". But it is strange that this feature will appear in the major companies in the examination questions, we discussed with relish.
Question 1:
Write the following code to run the result var a = 1;function fn () {if (!a) {var a = 2;} alert (a); // ?} FN ();
Question 2:
Write the following code to run the result var a = 1;function fn () {a = 2;return;function a () {}}FN (); alert (a); // ?
Fortunately, all this with ES6 let/const come to an end, ES in addition to global variables, others recommend the use of Let/const, if the Var is replaced with let, the variable promotion (hoisting) no longer exist.
function test () { alert (declaredButNotAssigned1);//Report Exception alert (DECLAREDBUTNOTASSIGNED2);//Report Abnormal alert ( Func); Report abnormal let declaredButNotAssigned1; Let DeclaredButNotAssigned2 = true; Let Func = function () {};} Test ();
This forces the programmer to develop good habits, variables need to "declare before use", or error.
The following is an excerpt from MDN about let's not occurring variable elevation description
In ECMAScript 6, let does isn't hoist the variable to the top of the block. If you reference a variable in a block before let the declaration for that variable are encountered, this results in a , because the variable is in a ' temporal dead zone ' from the start of the block until the declaration, processed.
typeof is no longer secure after you declare a variable with let
if (condition) { alert (typeof num);//error! Let num = 100;}
Previously can use typeof = = ' undefined ', to determine whether to introduce a certain lib, such as jquery
Determine if jquery introduced the IF (typeof $!== ' undefined ') { //do something} ...
jquery did not introduce, $ no declaration, this sentence will not be an error and affect the following code execution, but if the LET statement will be an error.
Related:
Temporal_dead_zone_and_errors_with_let
Why-typeof-is-no-longer-safe
JavaScript determines if the variable is undefined two different ways
Various variable promotion in JavaScript (hoisting)