我一直认为JavaScript源代码中的所有空格(空格,制表符,换行符)都是"相等的",即它们对于分隔语言元素(如标识符,关键字,运算符等)都是有效的。
但是,我注意到换行符与空格或制表符之间存在奇怪的差异。甚至在评论中!
这工作正常:(函数定义和函数调用之间的换行符,但没有分号)
var bla = function() { alert('hello') }
bla();
这也可以工作:(结束 } 字符和 bla() 函数调用之间的分号)
var bla = function() { alert('hello') };bla();
但是,这不起作用:(无论只有一个空格或制表符,还是多个空格或没有空格,都没有区别)
var bla = function() { alert('hello') } bla();
而且它变得更加奇怪。
这也不起作用:(用包含空格、制表符和分号的注释分隔)
var bla = function() { alert('hello') } /* ; */ bla();
但这确实:(包含换行符的注释)
var bla = function() { alert('hello') }/*
*/bla();
现场jsfiddle演示:
- 换行符(正常)
- 分号(正常)
- 空格或制表符(不正常)
- 包含空格、制表符和分号的注释(不正常)
- 包含换行符的注释(好的!
这是 JavaScript 中的一个错误,还是我错过了什么?
因为空格行为不当,而是归结于Javascript的"ASI"功能:"自动分号插入"。
这是Javascript语言首次引入时包含的功能。基本上,交易是这样的:
核心JS语言要求每个语句都以分号结尾。
但是,由于该语言针对的是网页设计师(当时他们不被认为是程序员),如果开发人员忘记包含分号,则解析器被修改为宽松。如果分析器认为缺少分号,但存在换行符,它将假设分号是有意的。
坦率地说,在语言设计中,这是一个非常糟糕的决定:它会导致许多已知的怪癖,从而导致很难调试的问题。特别是,您需要非常非常小心地围绕返回多行对象结构的语句return
但是,正如您的问题所展示的那样,还有很多其他方法可以使您发现。
这里要学习的教训很简单:始终在 JS 语句之间包含分号,即使它们似乎是可选的。
如果你真的对这个主题感兴趣,你可以在这里阅读更多关于ASI的信息,作为一个Javascript程序员,这是一件重要的事情。但一般来说,如果你只包括你的分号,你几乎可以忘记它。