为什么两个函数调用的括号之间的换行不被视为js中的两个语句?

bro*_*man 5 javascript syntax

为什么在js上做出这种糟糕的设计?是否有任何特殊原因设计这样的自动分号插入?

这是我的代码,它在chrome中的js中不起作用:

(function(){console.log("abc");})()

(function(){console.log("123");})();
Run Code Online (Sandbox Code Playgroud)

这是错误:

Uncaught TypeError: (intermediate value)(...) is not a function
Run Code Online (Sandbox Code Playgroud)

我知道这段代码的正确版本是:

(function(){console.log("abc");})();

(function(){console.log("123");})();
Run Code Online (Sandbox Code Playgroud)

我只是想知道为什么js语法设计得如此愚蠢.历史原因?

我也添加这个问题作为警告,每个人都尝试使用javascript的自动分号插入,请只需添加;它需要的任何地方,javascript的自动分号插入是垃圾.它没有像你期望的那样工作.

现有的答案对我来说太复杂了,所以我问一个新答案:

/sf/answers/199240891/

另一个看起来不错但不是工作案例2:

x=1

(function(){console.log("123");})()
Run Code Online (Sandbox Code Playgroud)

Ama*_*dan 4

链接问题的答案解释了 ASI 规范的三个规则,例如这个。长话短说:

  • 如果不起作用,请尝试使用分号。

  • 程序应该以分号结束。

  • 如果声明说“不能在此处放置换行符”,则用分号对其进行惩罚。

您的代码不满足任何条件。

  • 第一行可以返回一个函数,如果是这样,应该允许调用该函数;这样(第二行开头就不违法

  • 程序的第一行不是最后一行

  • 这里没有限制语法。

因此,没有自动分号适合您。

因此,有些人声称虽然(f(){})()语法是良好的 IIFE 语法,但改为这样做可能会更好!f(){}()

!function(){console.log("abc");}()

!function(){console.log("123");}();
Run Code Online (Sandbox Code Playgroud)

这按预期工作,因为!只是否定了函数应用程序的(丢弃的)结果,而且还因为!作为纯粹的一元运算符是继续第一行的非法字符(即f(){}()!不是一个东西)。这会触发规则 1,ASI 就会发生。

反驳是,它是丑陋的(即对于任何不熟悉这种做法的人来说,他们需要一段时间才能理解这样做的目的)!这个习语的目的)。

你的第二个例子本质上是相似的:就 JS 解析器而言,1是一个值(事实上它是一个整数并且不可能是一个函数,这对它来说有点丢失)。看一下这个例子,它在语法上与你的完全等同:

a=function(f) { console.log("A CALLED!"); return f; }
x=a
(function(){console.log("123");})()
# => A CALLED!
     123
Run Code Online (Sandbox Code Playgroud)

这里,是一个函数,因此可以将其作为参数a调用;打印到控制台后function(){console.log("123");}返回不变;function(){console.log("123");}然后()调用该返回值,并123打印出来。一切正常。因此,规则 #1 不会被触发,没有分号给你。