Make writing a habit together! This is the sixth day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.
\
Hi, I’m the watermelon guy. Today in a front-end communication group, a group of friends posted such a question.
function fn(a) {
console.log(a);
var a = 2;
function a() {}console.log(a);
}
fn(1);
Copy the code
It looks like it’s a variable lifting problem. Then I tried a guess, and sure enough, I got it wrong. Var and its variable promotion are really confusing.
Let’s start with the bottom line.
var
Var is the keyword used before ES6 to declare variables. Var looks clever, but he is very wrong in his work.
A variable declaration written in var in a block scope will run out to the nearest function scope or global scope.
There are also some special cases, such as with and try… Catch, they can form special block scopes to keep variables from going out.
A very classic cycle timer title is to examine this feature:
for (var i = 0; i < 5; i++) {
setTimeout(function(){
console.log(i);
}, i * 1000);
}
Copy the code
I’m not going to do this, because it’s so classic, so if you haven’t done it before, you can try it.
The solution is to use IIFE (execute function expressions immediately) to form a function scope that var does not overflow, although it is more common in real development to ditch var and use let/const that supports block scope.
If a variable name is not declared and is assigned an initial value without using var, it becomes a variable in the global scope.
function setA() {
a = 1;
}
setA();
console.log(a); / / 1
Copy the code
If you declare the same variable more than once, subsequent var declarations are ignored.
var a = 1;
var a = 2;
var a = 3;
Copy the code
Is equivalent to
var a = 1;
a = 2;
a = 3;
Copy the code
You can also think of a function declaration as a var declaration. Do not assume that the following var declaration overwrites the function declaration of the same name.
Promotion of declarations
Variable declarations and function declarations are hoist.
Var a = 1; var a = 1; var a = 1
This is the behavior of the compiler, so in terms of representation, the declaration is put at the beginning of the code, called promotion.
In addition to var/let/const variables being promoted, function declarations are promoted as well, and function declarations are promoted before variables are promoted, i.e., above variable declarations.
b();
var a = 1;
function b() { console.log(a) };
Copy the code
Is equivalent to
function b() { console.log(a) };
var a;
b(); / / output is undefined
a = 1;
Copy the code
One mistake is to mistake a function expression for a function declaration. Function expressions do not promote variables, remember.
Back to the subject
function fn(a) {
console.log(a);
var a = 2;
function a() { }
console.log(a);
}
fn(1);
Copy the code
First is the function argument A, which is equivalent to an external variable. The above code is equivalent to:
var a = 1;
(function() {
function a() {}console.log(a);
a = 2;
console.log(a); }) ();Copy the code
Here the function declaration has been upgraded to go to the top. So let’s think about boosting var a = 2. However, the declaration of function A has been improved, so the var declaration here is repeated, so we can remove var and get the above code.
We can easily see that the answer is:
ƒ a() {} 2Copy the code
In addition to the general declaration promotion, we also examine a more special case: where should we put the parameter declaration of a function?
The answer is to put it in an extra middle layer that wraps around the function body, not directly at the top of the function body.
Seriously, I might want to say hello to anyone who writes code like that at work.
The last
The real front-end development uses let/var in the actual work, and then the compiler converts it into ES5-compatible var code and releases it to the production environment.
Var is a bad culture, always showing off its blatant manipulation, especially when manipulated by a cheery interviewer.
The article was first published on my public account: front-end watermelon brother