Code runs in a block-level scope

Let’s start with an interview question

var a= 0
if(true) {console.log(a);  //[Function: a]
  a = 1
  console.log(a);  / / 1
  function a(){}
  a = 2
  console.log(a);  / / 2
}
console.log(a);  / / 1
Copy the code

See here does not feel that their brain is not enough, this operation results why so strange. But that’s okay. After you read the article, you’ll think that’s all there is to it. Follow my rhythm to try to analyze this interview question, to increase the interview knowledge for yourself

preface

JS scope: global scope, function scope. There is no concept of block-level scope. However, block-level scopes have been added in ES6. Block scopes are included by {}. The {} in the if and for statements are also block scopes.

Block-level scope

ES6 explained that block-level scopes can be declared with the new let and const commands. Variables declared cannot be accessed outside the scope of the specified block. Block-level scopes are created when:

  1. Inside a function
  2. Inside a code block (enclosed by a pair of curly braces)

Why add block-level scopes

Here are some of the things that happened before ES6 without block-level scopes

  • Variables declared in if or for statements are promoted to global scope
for(var i=0; i<=5; i++){console.log("hello");
}
console.log(i); / / 6
Copy the code
  • Variables declared with lets and const in block-level scopes are not externally accessible

parsing

var a= 0
if(true) {console.log(a);  
  a = 1
  console.log(a);  
  function a(){}
  a = 2
  console.log(a);  
}
console.log(a);  
Copy the code

In the block-level scope there is a function declaration, the function declaration is the first function name declaration, and then the function body assignment

  • The code is equivalent to the following
var a= 0
if(true) {var a
  a = function(){}
  console.log(a);  
  a = 1
  console.log(a);  
  // function a(){}
  a = 2
  console.log(a);  
}
console.log(a);  
Copy the code

Variables declared by var in the block-level scope are promoted to the top of the non-block-level scope

var a
var a= 0
if(true){
  a = function(){}  
  console.log(a);  //[Function: a]
  a = 1
  console.log(a);  / / 1
  // function a(){}
  a = 2
  console.log(a);  
}
console.log(a);  
Copy the code

Now we start executing the code, so the first print is the function, then a = 1 assigns 1 to a in the block-level scope, and the second print is 1. Function a(){}

  • Here we go!! A function defined in an if or for statement is synchronized to the same scope as the function

The value of variable A in the block-level scope is 1 and synchronized to the same scope as the function. The function scope is the global scope under Windows, so the value of a in the global scope is synchronized to 1

var a= 0   //a = 1
if(true) {// a = 1
  console.log(a);  //[Function: a]
  a = 1
  console.log(a);  / / 1
  function a(){}
  a = 2
  console.log(a);  
}
console.log(a);  
Copy the code

Further down, execute code a = 2 and assign 2 to A in the block-level scope. The third print is 2, and the last print is a in the global scope, which is 1. Now you get the idea. Did not understand the words can also see the following exercises

practice

var a = 0
if (true) {
  console.log(a);

  function a() {}
  a = 1
  console.log(a);
  function b() {}}console.log(a);
console.log(b);
Copy the code

As explained earlier, function name declarations in block-level scopes are promoted to the top of the non-block-level scope, and function body assignments are promoted to the top of the block-level scope

var a
var b
var a = 0
console.log(a);
if (true) {
  a = function (){}
  b = function (){}
  console.log(a);

  // function a() {}
  a = 1
  console.log(a);
  // function b() {}
}
console.log(a);
console.log(b);
Copy the code

The code starts executing, and the first thing to print is 0. The second print is [Function: a]. Function a() {} synchronizes the name of the function variable to function a() {}, so that the value of the global variable a is synchronized to function a() {}, a = 1, and the third print is 1. [function: a] [function: b] [function: b] [function: b]

var a = 0
console.log(a);  / / 0
if (true) {

  console.log(a);  // [Function: a]

  function a() {}
  a = 1
  console.log(a);  / / 1

  function b() {}}console.log(a);  // [Function: a]
Copy the code

conclusion

  1. Variables declared by var in the block-level scope are promoted to the top of the non-block-level scope
  2. When a function is declared in a block-level scope, the function name variable is synchronized to the same scope as the function