前端变态面试题

170 阅读2分钟

笔者最近无意看到的面试题,我只能吐槽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来单步调试看看流程