请教声明提升问题,怎么理解这个 fn() 的执行结果呢?

function a() {
    console.log(1);
}

function fn() {
    a();
    if (false) {
        function a() {
            console.log(2);
        }
    }
}
fn(); //a is not a function

请问为什么 fn()的执行结果是这样的呢 ?

if 不管是 true/false, 结果都是一样的。

阅读 1.7k
2 个回答

函数可以被有条件来声明,这意味着,函数声明可能出现在一个 if 语句里,但是,这种声明方式在不同的浏览器里可能有不同的效果。因此,不应该在生成环境代码中使用这种声明方式,应该使用函数表达式来代替。详情
根据官方文档,fn函数中的a

// 在Chrome里: 
// 'a' 变量名被提升,但是 typeof a 为 undefined
// 
// 在Firefox里:
// 'a' 变量名被提升. 但是 typeof a 为 undefined
//
// 在Edge里:
// 'a' 变量名未被提升. 而且 typeof a 为 undefined
// 
// 在Safari里:
// 'a' 变量名被提升. 而且 typeof a 为 function

这个问题跟变量提升有关,函数定义的时候是会有变量提升的,你这段代码其实相当于是下面这个代码。

function a() {
    console.log(1);
}

function fn() {
    var a;
    a();
    if (false) {
        a = function() {
            console.log(2);
        }
    }
}
fn();

fn函数中存在函数a,那么解析的时候,会在这个作用域的顶部先声明一个a变量,最后在定义a函数的地方会变成函数赋值,所以相当于定义了一个a,但是还没有赋值,你就马上将a当做函数执行,自然的,就报错:Uncaught TypeError: a is not a function;

推荐问题