关于变量提升你不知道的

192 阅读2分钟

大家都知道的变量提升都是什么,函数在当前上下文提前声明加定义,var声明的变量提前声明。

今天我要卖弄点小技巧,教大家一些关于变量提升你不知道的高逼格的小东西,面试的时候大家拿去吹吹牛皮还是小意思啦,另外,这是本 小掘二 第一篇文章,欢迎大家多多转发,收藏。有什么不严谨的地方大家评论区留言。

上面的回答都是老版本浏览器啦,新版本浏览器是怎么回事呢?

给大家一份代码,大家先自己先思考一下答案

=================引子======================

console.log(fn)      
 if(1==1){     
     console.log(fn)
     function fn(){
         console.log('ok')
     }
     fn=12;
     console.log(fn)
 }
 console.log(fn)

答案可以自行在浏览器验证 答案分别是 undefined fn 12 fn 看完答案是不是大呼 好家伙,为什么和我想的不一样呢?
别着急,让我来给大家慢慢解释

=================原理======================

新版本浏览器为了兼容ES3和ES6,规则处理的很复杂。

首先会进行全局变量提升,如果创建的函数出现在非函数或对象的大括号中(例如:判断体,循环体,代码块...),只会对函数进行全局的声明,不赋值。所以第一个log输出的是undefined

代码执行进入到了大括号中,如果大括号中出现了function xxx(){} ,此时大括号会形成一个私有的上下文, 私有上下文中的第一件事也是进行变量提升,此时的变量提升是对函数进行声明+定义。所以第二个log是fn

代码执行到function fn(){},会把私有上下文中之前对于fn的操作映射给全局一份,但是他之后的代码都是操作他私有的,和全局的fn没有关系了。所以第三个log输出12,第四个log输出fn

=================图解======================

无标题.png

=================扩展======================

动动你聪明的小脑瓜,快来解解这几道题吧。

{
    function foo() {}
    foo = 1;
}
console.log(foo);

----

{
    function foo() {}
    foo = 1;
    function foo() {}
}
console.log(foo);

----

{
    function foo() {}
    foo = 1;
    function foo() {}
    foo = 2;
}
console.log(foo);