解释一下这段代码

Ynl0ZQ
  • 25
function f() {
    console.log(1);
}
(function() {
    if(false) {
        function f() {
            console.log(2);
        }
    }
    f();
})();
回复
阅读 970
4 个回答

mdn上这么说的
理论上function name() {} 是整个函数提升的
但是有条件的提升在各个浏览器上表现可能不一样,也就是说,这个带有条件的时候,提升会被单独处理,也就是说 可能按照变量的方式处理了。
https://developer.mozilla.org...

楼上的解释有问题呀,下面的代码是没问题的:

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,是行不通的。

自执行匿名函数,有自己的作用域,因此访问不到外部的f函数,在内部调用的时候会报undefined

宣传栏