{
function foo() {
console.log(1)
}
foo = 1;
function foo() {
console.log(2)
}
foo = 2;
}
console.log(foo) // 1
console.log(window) // window中有属性foo:1
各位老师们,为什么这里输出foo是1啊?能不能帮小弟解释一下。
{
function foo() {
console.log(1)
}
foo = 1;
function foo() {
console.log(2)
}
foo = 2;
}
console.log(foo) // 1
console.log(window) // window中有属性foo:1
各位老师们,为什么这里输出foo是1啊?能不能帮小弟解释一下。
在浏览器里调试一下可以发现问题所在,在ES5里没有块级作用域的情况下,第一行 function foo
的时候,foo
就被挂载当成 window
的全局属性了,这时的 foo
是一个函数的指针,执行到 foo = 1
的时候,挂载在 window
上的 foo
不再以指针引用的形式存在了,变成了原始值 1
。这样后续 foo
的变化也不会影响 window
上挂载的 foo
的值了。我猜大概是这样的原理。
10 回答11.7k 阅读
2 回答3.2k 阅读✓ 已解决
2 回答4.3k 阅读✓ 已解决
3 回答1.9k 阅读✓ 已解决
2 回答1.7k 阅读✓ 已解决
4 回答2.5k 阅读✓ 已解决
5 回答3.8k 阅读
问就是未定义行为,不同的环境得到的结果不一样,所以也不要从语法层面去深究,会翻车的。
你这个例子还好,至少
最新FF
跟最新Chrome
还有IE10-
的表现几乎一致;Chrome50
表示有语法错误,得改成if(true)
,改了之后跟上面一致;IE11
则得到第二个函数(这是唯一一个我觉着能解释通的现象:先处理变量,后处理函数)。加个子函数,这个例子就变得更生猛了:
结果就是:
Chrome94
还很嘴硬地说是1
;FF94
直接说不知道(undefined
);如果哪个面试官拿这个考你,你得认真给他掰扯掰扯,说不定你还能获得成就“把面试官比下去了而被刷”。
突然有一个想法:就是用
babel
把这样一段代码转成AST
,看看社区对这个问题怎么理解的,不过我是懒(bu)得(hui)去做了。