JavaScript里的语句用分号结尾是个选项吗

您所在的位置:网站首页 mapstercam每行结尾加分号 JavaScript里的语句用分号结尾是个选项吗

JavaScript里的语句用分号结尾是个选项吗

2023-06-05 20:27| 来源: 网络整理| 查看: 265

    JavaScript里的语句用分号结尾是个选项吗 javascript 发布于 2016-10-26 起因

这个文章一开始回覆于这篇回答中: javascript初级问题

也有之前的朋友写信来问,因为在读到我个人写的一本电子书: 从ES6开始的JavaScript学习生活,繁体,gitbook。我在写作风格里有说明,这本电子书中的范例都是使用"不用分号(;)作为代码语句的结尾"的风格。

所以我把所有的内容整理出来到这篇文章,并针对一些常见的反对问题作解说回答。

觉得写得好的朋友请分享给你的朋友,或点个推荐。这些知识是很基本的,但可惜一直被忽视。

前言

先说明我并没有要大家都来不加分号,而是回答"为什么可以不加分号",或是"为何分号是选项可有可无?",或是"分号是在何时可以不加?何时又一定要加?何时又算多加了?"等问题。

"不用分号作语句结尾"并不是"完全不使用分号",而是该加的时候加,不该加的时候不加,不用分号作为语句结尾。实际上,我如果在改写别人的代码或是像原本函式库(如jquery)的风格是有用分号(;)时,为了统一撰写风格,也是会加的,基本上自己最近写的ES6、React、Redux等就不用分号(;)结尾。

分号(;)的作用

在JS里的分号(;)是什么作用?总结一下,它既是语句(表达式)的分隔,也可以作为语句的结尾。

但只认为分号(;)就一定是语句的结尾是有疑问的,下面这两个例子就是典型范例,也是很常见的错误:

//有问题的例子 function add() { var a = 1, b = 2; return a + b; }

或是像下面这个,也是很常见的错误示范:

//有问题的例子 function test() { return { test: true }; }

这两例的函数回传值必为undefined,而不是应该回传的值3与物件。为何?因为你有看到return先换行(回车),再接著要回传的值了吗?也就是说这两个代码在执行时,相当于下面这样的代码(我只写一个出来,另一例相同):

function test() { return; { test: true }; }

return因为先换了一行,视为语句结尾,所以根本没有可回传的值,也就是在上例子中,回车(\n)先把return结尾掉了,后面你加的分号(;)是结尾到下一行的。这逻辑代表回车(\n)在这一句语句结尾这功用上,比分号(;)还优先。

那为何回车(\n)或换行,可以作为语句的结尾?来源是由于ECMAScript的自动插入分号(Automatic Semicolon Insertion, 以下簡稱ASI)的标准。在语句或一段代码叙述后,加了回车(\n)后,JS剖析器会在执行期间自动帮你插入分号,这样理解了吗?所以不是回车(\n)的事,是因为自动帮你加分号作结尾了。

自动插入分号(ASI)这个规则一直在网上有争议,有一群人认为它是个容易造成误解的设计,有一群人认为它这设计是正确的,应该多多利用,就像不需要在一般情况下再多此一举,在语句后面加上分号(;)。不管你是支援哪一种,我认为都需要理解其中的内容,作为一个称职的JS开发者,这是很基础的一些知识。

自动插入分号(ASI)的5种例外情况

这里讨论的就是用回车(\n)或断行来作为语句的结尾,自动插入分号(Automatic Semicolon Insertion)标准的特例情况。在以下的5种情况是用回车(\n)或换行,是不会作自动插入分号来让语句作结尾。虽是说"例外情况",但大概也是每天都看得到,只是常不知道为何会这样而已,看了你就知道了。大致说明如下:

1. 当这一行的语句是没关闭的情况

例如数组(阵列)、对象(物件)文字字面、圆括号之类,或是最后是个点号(.)或逗号(,)时,也就是如果把这行结尾,就会产生不合法语句的情况。

注: 遇到等号(=)算未完整的表述式,如果指定值在下一行也会略过自动插入分号结尾作用

这种例子很常见,通常是在分开内容太长的语句,或是让值写得清楚的地方。我举下面的两个合法语法范例,你会很容易理解回车(\n)会在何时自动结尾,虽然这些例子是不好阅读的例子,一般情况我们会用来分隔比较长的语句:

//第一例 var a = [ 1, 2, 3, ] //第二例 function test(a, b, c){ console.log(a,b,c ) } 2. 这一行是++或--

这规则是很怪异的,从来没看过有人这样写过。JS会认为++与--在这一行是要准备来运算执行下一行的值,所以不结尾。下面是个合法范例:

a=1 -- a console.log(a) 3. 这一行是for()、while()、do、if()或else,但没有用花括号({})时

这简写语法也很常见,每天都会用到,是个当花括号({})区块中执行代码不多时用的语法。以下为范例:

if(null==undefined) console.log(true) else console.log(false) 4. 下一行的开头是([)、(()、(+)、(*)、(/)、(-)、(,)、(.),或二进位运算子(例如~ & |),可以与这行组成一个表达式时

以下为范例:

function test(){ return 1 +2 -3 } console.log(test())

下面这个例子刚好与第一点颠倒的写法,也很常见,也是一个用于长语句的写法。有人喜欢用这种的写法,有些人喜欢用第一点的写法:

var a = [1 ,2 ,] 5: 空白语句,不会自动插入分号作结尾

这与上面第3点有相关,有时候会看到有人犯了这个常见错误。下面是个错误例子,不论if这行与else这行间有没有换行,或是换了几百行,都不会自动插入分号作结尾:

//错误例子 var i = 10 if (i === 5) else console.log(false)

不过,你可以加上分号在if(...)这行最后,让语法合法可被执行。但真心没见过有人这样用,控制流程逻辑不对才会这样写。下面为合法例子:

//合法例子 var i = 10 if (i === 5); else console.log(false)

以上为用回车(n)作为语句结尾的的5个例外情况,其他都会自动帮你插入分号作结尾。

所以依这个解说,最一开始的例子中的return后面多了一个换行就会产生错误的回传值。与return有同样情况的还有几个,像continue、break、throw等四个关键字,这些如果先换行,然后在下一行再加分号也是会变成两个不同的语句,因为在换行时已经自动插入分号结尾掉。

一个小常识是,分号(;)除了作为语句结尾或分隔外,它与JS中的其他符号有差异,是它自己本身可以形成一个合法的语句(表达式)。你可以在程式码里只输入一个分号(;),它是合法而不会报错的,其他的符号(例如:,:+-*/%)都会报错。

一定要使用分号的情况

分号(;)的用处不是只有语句结尾,它在某些语法中,具有分隔表述式或语句的功用。以下情况必用分号(;)。

1. for语句圆括号(())中的三个表述式彼此之间:

很常用到,不多加说明了,以下为例子:

for(var i=0 ; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3