今天看到群里大佬分析了一个问题函数提升与变量提升_预编译然后不出意料的困住了俺,答案是2,1

经过百度加上大佬解惑理解了了原因,

首先说百度来的吧,关于函数提升和变量提升,两者之间函数的提升具有最高优先级,变量提升的优先级要弱于函数,且不会被变量声明替代,只会被变量赋值覆盖。

然后附上编译原理:

编译前的代码:
var foo = 3;

function hoistFunction() {
    console.log(foo); // function foo() {}

    foo = 5;
    
    console.log(foo); // 5

    function foo() {}
}

hoistFunction();
console.log(foo);     // 3

预编译后:

var foo = 3;

function hoistFunction() {
   var foo;

   foo = function foo() {};

   console.log(foo); // function foo() {}
   
   foo = 5;

   console.log(foo); // 5
}

hoistFunction();
console.log(foo);    // 3

可以看到函数在编译阶段是先于变量的。

在这个时候我已经觉得我大致理解了函数提升和变量提升,然而回头看题目仍旧解不出来为什么是2和1

经过询问大佬得知,变量a和函数a都是一个a,故而 a=1属于全局作用域,而a=2则是私有的函数作用域

a = 1覆盖了函数a导致外面的a的值变为了1,而后面的a = 2有因为块级上下文的关系是私有的,全局上无法获取。所以外面的a=1。

附:记住一句话就是 新版浏览器 为了兼容es6  
 {} 里面的 funtion  let const 都会生成块级上下文,  上面的所有操作会映射给全局一份,下面的 所有操作是私有的