在代码块中定义的内部函数的语义是什么?

时间:2014-02-20 10:24:27

标签: javascript function

前提:函数文字仅在执行相应的赋值时绑定到它们的名称(除非匿名使用)。例如,可以像这样进行条件定义:

var fn;
if (some condition) {
    fn = function() {
        // some code
    };
} else {
    fn = function() {
        // some different code
    };
}
另一方面,

内部函数的行为就像它们总是绑定到它们的名称一样,在相应的范围内,忽略任何代码路径注意事项:

function outer() {
    inner();
    return;

    function inner() {
        // some code
    }
}

我的问题是,当内部函数在函数定义以外的代码块中定义时,它们如何表现?以下是合法的吗?标准是否未定义?

function outer() {
    if (true) {
        inner();

        function inner() {
            // some code
        }
    }
}

我对this JSFiddle的测试似乎表明它适用于大多数浏览器,包括Chrome,Safari和IE 8-11,但不适用于Firefox。这是Firefox中的错误吗?

1 个答案:

答案 0 :(得分:4)

它们没有 - 实际上某些浏览器会因代码而失败,尤其是当您处于严格模式时。

执行功能时,分两步完成:

首先,找到所有varfunction X声明并将其提升到顶部。请注意,如果是var x = 1,则只会暂停var x部分,并将x = 1保留在原始位置。

然后运行代码。

所有var语句都会被提升,即使它们位于if块中。例如:

function test() {
    if( false) {
        var x = 1;
    }
    alert(x); // you may expect ReferenceError, but in fact you get undefined
};

这样做是安全的,因为它只是说“这个变量可能存在于某个时刻”。

然而,功能却非常不同,因为功能内容也被提升了。这可能会导致条件中定义的函数出现重大问题,因此虽然某些浏览器会很乐意将它们提升(将最后一个定义为最终定义),但其他浏览器会失败。

function test() {
    if( true) {
        function derp() {alert("True");}
    }
    else {
        function derp() {alert("False");}
    }
    derp(); // an ignorant programmer may expect True,
            // only to find they get False, or an error
}

我希望这是有道理的!