Home >Web Front-end >JS Tutorial >Identifier promotion problem in JavaScript_javascript tips
JS has variable promotion. This design is actually poor, or it is a side effect of language implementation. It allows variables to be accessed without declaration, or declared later and used first. Newbies are confused by this, and even many veterans who have used JS for many years are confused. But after ES6 added let/const, the variable Hoisting no longer exists.
1. The variable is not declared, use it directly
function test() { alert(notDefined); } test(); // ?
It is natural to report errors
2. Variable declaration at the end
function test() { alert(declaredButNotAssigned); // undefined var declaredButNotAssigned; } test();
Output undefined, the result is improved compared to the above example, no error is reported, the code can run, but the variable value may not be what the programmer expected.
3. Declare the variable at the end and assign a value to the variable at the same time
function test() { alert(declaredAndAssigned); // undefined var declaredAndAssigned = 1; } test();
The result is the same as two. Obviously, 1 will not be output just because of the assignment.
Both two and three have variable hoisting (Hoisting), simply defined
Variable promotion: In the specified scope, in terms of code order, variables are used first and then declared, but the "accessibility" of the variable at runtime is promoted to the top of the current scope, and its value is undefined, and there is no "availability" ".
The emphasis here is on “code order” and “running order” because most of the time the code we write is executed sequentially, that is, “code order” and “running order” are consistent. This is also consistent with the thinking process of the human brain. For example, programmers with experience in C language
#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 it. The code sequence and running sequence are consistent, that is, normal operation.
If the order is reversed
#include <stdio.h> int main() { printf("%d, ", x); // error int x = 1; }
At this point, the compilation cannot pass. But it can be written in reverse in JS, see 2 and 3.
Therefore, programmers with experience in C-like languages know that variables need to be declared first and then used, otherwise an error will be reported. In JS, there is a phenomenon of variable promotion, which can be used first and then declared. The experience of C is used in JS, and confusion arises.
4. Function expressions also have variable promotion
function test() { alert(func); // undefined var func = function() {}; } test();
But if you want to use this func, it’s not possible
function test() { alert(func); // undefined func(); // 报异常 var func = function() {}; } test();
The result func is undefined, and calling func will report an exception. Accessibility and availability are mentioned in the above definition and correspond to the following statements.
Accessibility: alert(func), output undefined, can be run, func can be accessed.
Availability: func() reports an exception and func cannot be called normally, indicating no availability.
Second, third, and fourth are all variables declared using var. Function declarations in JS will also be improved, but this "variable" is special. It is a function type (can be used as a function, method or constructor). Its name (identifier) is also hoisted to the top of the current scope.
5. The name of the function declaration will also be promoted to the top of the current scope
function test() { alert(f1); // function f1(); // "called" function f1() { alert('called'); } } test();
We see that f1 is declared at the end of the code and f1 is used first. Both alert(f1) and f1() are executed normally, indicating that accessibility and usability are both present.
As mentioned before, variable hoisting is of no use. It is a poor design of the language. The good habit is to "declare first and then use". This feature will also appear in many interview questions of large companies
Question 1:
// 写出以下代码的运行结果 var a = 1; function fn() { if (!a) { var a = 2; } alert(a); // ? } fn();
Question 2:
// 写出以下代码的运行结果 var a = 1; function fn() { a = 2; return; function a() {} } fn(); alert(a); // ?
But this all ended with the arrival of let/const in ES6. Except for global variables, everything else in ES uses let/const. After replacing var with let, variable promotion no longer exists.
function test() { alert(declaredButNotAssigned1); // 报异常 alert(declaredButNotAssigned2); // 报异常 alert(func); // 报异常 let declaredButNotAssigned1; let declaredButNotAssigned2 = true; let func = function() {}; } test();
This forces programmers to develop good habits. Variables need to be "declared first and then used", otherwise an error will be reported.
The following is excerpted from MDN’s description of variable promotion when let does not occur
After using let to declare variables, typeof is no longer safe
if (condition) { alert(typeof num); // Error! let num = 100; }
In the past, you could use typeof == 'undefined' to determine whether a certain lib was introduced, such as jQuery
// 判断jQuery是否引入了 if (typeof $ !== 'undefined') { // do something }...
jQuery is not introduced and $ is not declared. This sentence will not report an error and affect the execution of the following code, but if it is declared by let, an error will be reported.
The above is the entire content of this article, I hope you all like it.