level 2
【提示:要读懂此文必须先了解清楚 js 的作用域概念】
这是函数声明在块级作用域里的一种诡异表现。
function a 这个函数在解析代码的时候会首先进行声明,在声明的时候会声明到当前作用域的顶端,但是由于是在代码块里,它只是声明了 a 这个标识符但是没有赋予其内容。然后开始从头到尾执行代码。
var a=10; //a=10
执行完这一句之后进入了代码块{}。到这里,诡异的事情出现了。
由于代码块具有块级作用域,function a 的函数声明会先在块级作用域声明一个名为 a 的局部变量,然后 function a 的函数定义在这个时候被写入了这个变量。然后开始执行代码块内的代码。
此时在代码块内访问标识符 a 会得到块级作用域的局部变量 a 。
a=99; //全局a=10,局部a=99
接下来就到最诡异的地方了,本来 function a 的函数声明已经被提升,内容也已经被写入然后被覆盖了,解释器在经过 function a() {} 这一句时本不应该再有任何动作,但是实际上不是。解释器在经过这一句时会把局部变量 a 的内容赋值给外层作用域的变量 a ,而且之后在代码块内访问标识符 a 仍然会得到块级作用域的局部变量 a 。
function a() {} //全局a=99,局部a=99
a=30; //全局a=99,局部a=30
之后代码离开了代码块{},块级作用域被销毁,局部变量 a 消失不见。
console.log(a); //99
目前并不知道解释器为何会具有这种行为,网上也很少提及这种现象,但由这种现象可以得出一个警示:要谨慎处理 js 中存在的提升机制与各种作用域。
2020年05月31日 21点05分