JavaScript实验:语句结束处的分号

在JavaScript语法中,每行语句结束处的分号不是必需的,因此完全可以写出不使用任何分号的JavaScript程序。当某行语句结束而又没有出现分号时,JavaScript引擎会自动插入分号。比如以下代码:

var a  
var b  
var c  

该代码等价于:

var a;  
var b;  
var c;  

JavaScript对于一行语句是否已经结束的判定条件为:尝试将下一行的代码与本行代码相连,如果相连后的语句合法,那么本行代码未结束;否则,本行代码判定为结束。以上面的代码为例,由于var a var并不合法,因此第一行代码var a的结尾处会被插入一个分号。与之相反的例子为:

var a  
=
3  

上述代码等价于:

var a = 3;  

不使用分号的问题

如果JS程序编写过程中不使用分号,那么程序中的语句分隔是由JavaScript引擎来自动分析完成的。这可能会带来一些问题,导致JS引擎不按照编程人员的预期添加分号。事实上,JavaScript这一自动分号插入特性成功入选为“史上7大编程语言及操作系统设计错误”之一。这一特性所带来的问题包括:

  • 下一行语句以(、[、/、+、-这5个字符开始而出现的情况。考虑以下这个例子:
var a = b + c  
(x + y).print()

在编程人员的预期里,这是2个语句;但是由于JS引擎可以顺利地将这两行合并在一起,因此实际代码运行时,这是1个语句,等价于:

var a = b + c(x + y).print();  
  • ++或者–的问题。考虑以下这个例子:
x  
++
y  

该代码会被JS引擎处理为以下结果,而这不一定是程序员所预期的:

x;  
++y;
  • return、break、continue问题。考虑以下这个例子:
return  
true  

该代码会被JS引擎处理为以下结果,而这很可能不是程序员所预期的:

return;  
true;  

解决方案

为了解决上述3个问题,保证程序编写的正确性,有两种做法:

  1. 在每一行JavaScript语句结束处添加分号。
  2. 尽量不使用分号,但对于以(、[、/、+、-这5个字符开始的语句,在语句前添加分号。

上述第二种做法的例子如下:

var a = b + c  
;(x + y).print()

从个人角度而言,我偏好第一种做法:在每一行JavaScript语句结束处添加分号;这种做法与C、Java程序的编写行为是一致的。不过,也曾看到过一些不同的意见。比如这篇文章的作者就认为不应该采用第一种做法,没必要在JavaScript程序中使用那么多的分号。他认为在实际开发过程中,上述3个问题事实上只会存在第一个,而这个问题完全可以通过在所有以(、[、/、+、-这5个字符开始的语句前添加分号来加以解决。