笔者最近无意看到的面试题,我只能吐槽js怎么这么多坑,笔者已经被虐的体无完肤了,记录一下吧
1、堆栈内存
var a = 0;
if (true) {
a = 1;
function a() {};
a = 21;
console.log(a)
}
console.log(a);
在笔者的认知当中ES5当中不存在块级上下文,因此输出 21 21
然后总有那么多的意外突如其来。
1、IE<=10中 21 21
2、新版浏览器中 21 1
在js中的概念当中每当执行一个script或者调用一个函数时候,一个新的执行上下文
就会被创建。一个执行上下文的生命周期可以分为两个阶段
创建阶段
在这个阶段中,执行上下文会分别创建变量对象,建立作用域链,以及确定this指向。
执行阶段
创建完成之后,就会开始执行代码,会完成变量赋值,函数引用,以及执行其他代码。

--变量对象(Variable Object)
1、建立arguments对象:检查当前上下文中的参数,建立该对象下的属性与 属性值
2、检查当前上下文的函数声明,也就是使用function关键字声明的函数。在变量对象中以函数名建立一个属性,属性值为指向该函数所在内存地址的引用
3、检查当前上下文中的变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,属性值为undefined
如果变量与函数同名,则在这个阶段,以函数值为准

这也就是我们常常提到的js预解析的机制
IE<=10
预解析 a=>function a(){},由于没有块级上下文,所有的a都挂载在window这个大对象下,因此修改的全是全局的a

高版本浏览器
高版本浏览器为了向前兼容ES3、向后兼容ES6,做了特殊处理
1、{}中的function在全局下只声明不定义(也就是undefined)
2、{}中出现function/let/const会创建一个块级上下文
console.log(a) //undefined 预解析完成时
var a = 0;
console.log(a) // 0
if (true) {
console.log(a) //function a(){} //块级上下文预解析完成时
a = 1;
function a() {};
a = 21;
console.log(a) //21
}
console.log(a); //1

当然我们也可以通过debugger来单步调试看看流程
