function f() {
console.log(1);
}
(function() {
if(false) {
function f() {
console.log(2);
}
}
f();
})();
function f() {
console.log(1);
}
(function() {
if(false) {
function f() {
console.log(2);
}
}
f();
})();
楼上的解释有问题呀,下面的代码是没问题的:
function foo() {
console.log(1);
}
(function() {
if(false) {
function f() {
console.log(2);
}
}
foo();
})();
js
文件是一个文本文件。当它被符合ECMA-262
标准实现的引擎(编译器)读取时,会经历以下阶段:以文本形式读取
=> 词法分析(Tokenization、Parsing等)
=> 编译(Compilation)
=> 优化(Optimization)
然后才会以机器可识别的语言执行。
在ECMA-262
标准中,以function
关键字进行的函数申明中的函数名变量将得到变量提升。
因此,当在闭包函数中以function
关键字申明变量f
时,变量f
将会得到变量提升。而变量f
的作用域为闭包函数内,所以此时相当于在闭包函数内执行了var f;
。即只申请了变量名及空间,但未进行任何赋值。
当运行至if (false)
语句时,由于此时并未进入条件分支,所以并未对f
变量进行赋值。当对f
以函数方式调用执行时,因为f
未进行任何赋值,所以是无法调用成功的。
至于闭包外的f
函数,因为其作用域在闭包外,如果闭包函数内并未申明f
变量,那么会根据标准从词法上下文中查找f
,那么就会找到闭包外的f
变量;但问题中,在闭包函数内同时申明了变量f
,因此只会使用闭包内的变量f
,而恰巧这个变量f
没有进行赋值,所以在闭包内以函数方式调用f
,是行不通的。
10 回答11.1k 阅读
6 回答3k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
3 回答2.1k 阅读✓ 已解决
mdn上这么说的
理论上function name() {} 是整个函数提升的
但是有条件的提升在各个浏览器上表现可能不一样,也就是说,这个带有条件的时候,提升会被单独处理,也就是说 可能按照变量的方式处理了。
https://developer.mozilla.org...