The premise

As we all know, js variable promotion is annoying. Most common languages are function declaration promotion, which is easy to understand and convenient for programmers, but variable promotion often produces all kinds of unexpected output results. Brendan Eich, the father of JS, said this on Twitter,

var hoisting was thus unintended consequence of function hoisting, no block scope, JS as a 1995 rush job. ES6 ‘let’ may help.

When developing JS, the demand was too rushed. When developing function improvement, it accidentally brought about var variable improvement.

example

1 ️ ⃣

var a = 1
function f() {
    if(a) {
        var a = 10
    }
    console.log(a)
}
f()
// the result is undefined
Copy the code

At first glance, it looks like10If you look at it again, it turns out to be1But it turns out thatundefined.

When f is executed, the declaration of functions and variables will be improved. Therefore, for F, var a will be improved and initialized as undefined. At this time, a in F is undefined, rather than the external A of our intuition, so it will not match the judgment logic. A will not be assigned, so the output a will be undefined.

2 ️ ⃣

var a = 1
function f() {
    if(a) {
        let a = 10
    }
    console.log(a)
}
f()
// The result is 1
Copy the code

If var a is changed to let a, then the output will be 1. This is the old saying about block scope. The a in let A is only valid in the block, and once the block is out, the scope is invalid. Changing if to a normal block gives the same result as follows:

var a = 1
function f() {{let a = 10
    }
    console.log(a)
}
f()
// The result is 1
Copy the code

So here’s the classic interview question that I think you know,Type the results on the public screen (bushi).

function f() {
    var a = 0
    for(let a = 0; a < 5; a ++) {
    }
    console.log(a)
}
f()
Copy the code

3 ️ ⃣

So let’s change it a little bit,

var a = 1
function f() {
    if(a) {
       function a(){}}console.log(a)
}
f()
// the result is undefined
Copy the code

Function a() {} function a() {}

I said it was undefined. Function is created, initialized, and assigned together. That’s true for the most part, but there’s a block scope that’s generated, and it’s specified on the MDN,

Function declarations are also restricted to the block in which they are declared:

foo('outside');  // TypeError: foo is not a function  
{  
   function foo(location) {  
      console.log('foo is called ' + location);  
   }  
  foo('inside'); // Works normally and prints 'foo is called inside'
}
Copy the code

Send subtopic

function f() {
    return ff()
    var ff = function() {return 1}
    function ff() {return 2}}console.log(f())
Copy the code

Please type your answer in the comments section