关于javascript:无法访问的条件块中的函数声明

Function declarations in unreachable conditional blocks

很有意思。 你为什么这么认为?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var fn1 = function() {
    function fn2() {
        return"fn2 initialize...."
    }

    if (false) {
        function fn2() {
            return"fn2 if --> false"
        }
    }
    return fn2();
}

fn1();  //"fn2 if --> false"

或者更有趣;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var fn1 = function() {
    function fn2() {
        return"fn2 initialize...."
    }

    if (false) {
        function fn2() {
            return"fn2 if --> false"
        }
    }
    return fn2();

    function fn2() {
        return"fn2 return after"
    }
}

fn1();  //"fn2 return after"


该代码中发生了两件事,其中一件是指定的行为,另一件在语法上无效(现在),其结果因JavaScript引擎而异。

无效位是您不能在条件块中具有函数声明。例如,这个位无效:

1
2
3
4
5
if (false) {
    function fn2() {
        return"fn2 if --> false"
    }
}

一些引擎会将其视为函数声明,这意味着它不受逐步代码流的影响(因为函数声明不是,它们发生在逐步流程之前)。

其他引擎将(实际上)重写为您的函数表达式,将其置于逐步流程中。

我相信ECMAScript6将解决这个问题。

指定的位涉及在同一范围内只有两个声明,例如:

1
2
3
4
5
6
7
8
9
10
11
12
var fn1 = function() {
    function fn2() {
        return"the first fn2"
    }

    return fn2();

    function fn2() {
        return"the second fn2"
    }
};
fn1();  //"the second fn2"

规范明确规定范围内的所有函数声明都按源代码的顺序处理,因此上面(删除了无效位)可靠地使用第二个fn2,而不是第一个。