在JavaScript中关闭函数之前是否需要分号?

时间:2019-05-18 03:37:33

标签: javascript syntax compilation

我想知道这是否是编译器错误,或者这是应该的方式。

使用node.js v10.15.3,此代码引发错误:

var x
x = false
(function y() { console.log('foo') }())

但是此代码可以正常工作:

var x
x = false;
(function y() { console.log('foo') }())

与众不同的是分号。错误消息是:“ TypeError:false不是一个函数”,所以似乎没有分号,编译器将“ false”关键字解析为函数调用后的打开的paren,就像我写“ x = false ()”。我花了很长时间才弄清楚我的代码出了什么问题(显然,它比上面的示例更复杂。)这是我一生中最宝贵的一部分!

我的问题是:为什么?我以为行尾不需要分号?我刚刚读过ECMA spec on semicolon insertion,试图弄清楚这一点,但对我来说还是有点模糊。

我想这个故事的寓意是继续前进并以分号终止所有行。有趣的是,作为C程序员,这是我的习惯,而我只是在试图赶上时代的步伐,放弃所有不必要的分号。

3 个答案:

答案 0 :(得分:2)

JavaScript解析器见此

var x
x = false
(function y() { console.log('foo') }())

是这样的:

var x;
x = false(function y() { console.log('foo') }());

,这意味着您正在尝试调用false作为函数。这是因为JS解析器总是尝试获取最长的表达式。

在大多数情况下,编写带有或不带有分号的JS只是样式问题。但是,在以下情况下,您需要添加分号:

  • 有两行代码,并且
  • 第一行以可能的标识符(或关键字,例如ifwhile)结尾,并且
  • 第二行以方括号开头。

在这种情况下,应将分号添加到第一行的末尾或第二行的开头。

答案 1 :(得分:0)

关于将false称为函数是正确的。 您的第一个代码块等效于此:

var x
x = false(function y() { console.log('foo') }())

由于没有分号分隔行,因此js解释器调用关键字false,将函数y作为参数传入。显然这会导致错误,因为false不可调用。

在这种情况下几乎需要使用分号,其中,圆括号内的空白是一行上的毛皮字符。仅在必要时使用分号的一种方法是将它们放在开括号之前,如下所示:

var x
x = false
;(function y(){...})

答案 2 :(得分:0)

在某些情况下,换行并不重要。如果代码是正确的语法而没有换行符。

请考虑以下代码段,其中使用两个()调用嵌套函数,并且调用之间用一行分隔。但这没关系。

function x(){
  return function(){ return 6}
}
let a =
x()

()
console.log(a) //6

以上行仍将被评估为

let a = x()()

一般规则是,只要没有分号,代码就有意义并且不会抛出错误。它不会在其中插入半色。仅在没有其他选择时才插入分号。