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