JS之变量提升到底有多少坑
什么是变量提升:当栈内存(作用域形成),JS代码自上而下执行之前,浏览器首先会把所带 var / function 关键字的进行提前声明 或者 定义 ( 这个过程也可以叫预编译 ),预编译阶段也有几点注意事项,咱们来看一看。
在变量提升阶段:
1.带 VAR 的只声明未定义,而带 FUNCTION 的声明和定义都完成了

在全局作用域下声明就相当于是给 window 对象添加了属性,属性名能重复嘛?答案肯定是不可以的,还有网上有很多资料说函数的优先级大于变量的优先级,我个人感觉这种说法不合理,大家一起来看一道题:

那从上面可以看出,根本就没有什么优先级,只有提升不断重新赋值而已。
2.变量提升只发生在当前作用域下(例如:开始加载页面的时候只对全局作用域下的进行提升,因为此时函数中存储的都是字符串而已)

3.变量提升只对等号左边的值进行处理,例如:

4. 带 function的 在老版本浏览器渲染机制下,声明和定义都会处理,但是为了迎合ES6中的块级作用域,新版浏览器对于函数(在条件判断中的函数),不管条件是否成立,都只是先声明,没有定义,类似于 var,但是在 条件成立的情况下第一件事并不是代码执行,而是类似于变量提升一样,先把fn 声明和定义了

5.带关键字 VAR 和 不带关键字 VAR 的区别:

var 声明一个变量其实可以说是给 window 全局对象设置了一个属性,变量的值就是属性值,私有作用域中声明的私有变量和 window 无关,全局变量和 window 中的属性存在 “ 映射机制 ”,从赋值可以看出,window.a 改变了变量 a 的值。
不使用 var 的话 可以理解为给 window 对象 添加了一个属性,没有提升,此时作用域链中没有这个 b 所以就会报错。
以上就是本人对 var 变量提升的理解及认知,面试的时候也有会不少公司问到,其实就一句,不想有变量提升 可以使用ES6中 let ,但是变量提升你还不能不掌握 ,在这里就不说 let 了,最后给大家来一道面试题开开胃,下方附图片及代码

f = function () { return true; }
g = function () { return false; }
~function () {
if (g() && [] == ![]) {
f = function () { return false; }
function g() { return true; }
}
}();
console.log(f());
console.log(g());
这道题只适用于新版浏览器,不要怀疑题目给错了,各位看看考点在那里吧
还有那句话:如有不对之处及不周之处请大佬们指出,也希望对一些人有所帮助,咱们下次再会!