还是来自贴吧的题目
var a=1
{
a=3
function a(){}
a=4
function a(){}
a=5
}
console.log(a)
求结果?
第一眼我觉得是1
毕竟function a会提升 形成遮蔽
块级作用域内的a都会等同let 修饰
然后我跑了下 node下报错
也确实 严格模式下不能这样写
于是去浏览器跑了下
结果输出4
???喵喵喵???
这不科学的感觉油然而生
于是断点跟踪:
提升~
这里已经赋值到全局了
但是 a=5没有到全局
加一行看看
确实 之后就是表现出let的修饰行为
总结下 :
从现象来看 大概结论就是 松散模式下 支持let的环境,
function 提升区域内没有修饰的同名变量会被视为var修饰
之后的会被视为let。
但这一行为我没找到具体规范说明做支撑,不确定其它浏览器环境表现是否一致。
ps:如果你试过严格模式 只用一个function a就会看到块级内a是被当作let修饰 外部不影响
去掉严格模式就会发现function a前的都会引用到全局,也就是被当作var对待了
{
function a(){}
}
console.log(a)
输出function a
{
function a(){}
a=2
}
console.log(a)
输出function a
{
a=2
function a(){}
}
console.log(a)
输出2
是不是 很神奇~
var a=2
{
function a(){}
}
console.log(a)
这里输出 function a
可以看出 function提升是穿透了块级
但它是在执行到块级的时候才提升的
它给的例子里 在方法提升过程中 不同内核浏览器执行赋值的位置不一致