大家都知道的变量提升都是什么,函数在当前上下文提前声明加定义,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
=================图解======================
=================扩展======================
动动你聪明的小脑瓜,快来解解这几道题吧。
{
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);