关于javascript:TypeError,带有两个连续的自执行匿名函数

TypeError with two consecutive self-executing anonymous functions

这个问题的灵感来自于此处接受的答案。 为什么下面的代码警告"先",然后"秒",然后错误输出TypeError

1
2
3
4
5
6
7
8
(function() {
    alert('first');
}())


(function() {
    alert('second');
}())

给出的解释是第一个函数的返回值正在尝试调用。 但为什么会这样呢? [另外,为什么在第一次自我执行后没有分号插入添加分号?]


没有分号,它将评估为:

1
2
3
4
5
(function() {
    alert('first');
}())(function() {
    alert('second');
}())

第一个函数被执行,因为它没有返回任何东西,它进一步评估:

1
2
3
undefined(function() {
    alert('second');
}())

然后执行第二个函数,它再次返回undefined,所以:

1
undefined(undefined)

当然这不起作用(TypeError因为undefined不是函数)。单独的函数调用应该用分号分隔,因为每个语句实际应该是。


ASI,自动分号插入。你的代码应该是这样编写的:

1
2
3
4
5
6
7
8
(function() {
    alert('first');
}()); //<--semicolon


(function() {
    alert('second');
}()); //<--semicolon

相反,这是采取的步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
(function() {
    alert('first');
}())


(function() {
    alert('second');
}())

//now, the interpreter guesses that you mean to concatenate the two
(function() {
    alert('first');
}())(function() {
    alert('second');
}());
//it also inserts a semi-colon where it should've appeared at the end of the script

//first function doesn't return anything === returns undefined
undefined(function() {
    alert('second');
}());

//second function doesn't return anything === returns undefined
undefined(undefined);
//however, the braces stay, since they can also mean function execution

undefined不是函数,因此无法执行,因此会出现TypeError。


之所以发生这种情况,是因为这是解析程序的方式。我们可以将该计划作为

1
 (some stuff) (some more stuff)

很明显,这应该尝试将some stuff称为函数。当然,分号可以解决问题,你希望分号插入可以自动完成。在不知道详细的插入规则的情况下,我只想说没有插入任何内容,因为规则是专门设计的,不会改变其他明确定义的行为。

当然,您可能不会认为这种行为"定义明确"。但语言规则在任何情况下都不能很好地运作。