最近,从Java语言中省略分号似乎很流行。几年前有一篇博客文章强调,在Javascript中,分号是可选的,并且文章的要旨似乎是您不必理会它们,因为它们是不必要的。被广泛引用的帖子并没有给出不使用它们的任何令人信服的理由,只是将它们排除在外几乎没有副作用。

即使GitHub也跳上了无分号的行列,要求它们省略了任何内部开发的代码,并且其维护者最近对zepto.js项目进行的提交已删除了代码库中的所有分号。他的主要论据是:


这是他的团队的优先事项;
不用打字

还有其他充分的理由将他们排除在外吗?

坦白说,我看不出没有理由要忽略它们,当然也没有理由回过头来删除它们。这也违背了(多年的)推荐做法,我并不真的赞成“货运邪教”的说法。那么,为什么最近都讨厌分号?短缺迫在眉睫吗?还是这只是最新的Javascript时尚?

评论

“建议的实践年份”指的是一个列入黑名单的SO民意调查标签的问题,该问题不太可能使其有权威地支持任何意见

@gnat只是因为人们讨厌SO上的问题并不能使它成为人们观点的较无效来源。

@gnat有时“专家认为在StackOverflow上不合适的问题”是非常权威的。伤心但真实。

@gnat实际上列入黑名单的问题有一些非常有趣的例子,说明了为什么省略了;可能会破坏您的代码。因此,我认为这对于此问题是有用的参考。

这可能与2010年代初期时尚潮人的兴起有关。

#1 楼

我想我的理由是最无聊的:我同时用太多不同的语言(Java,Javascript,PHP)编程-需要';'而不是训练我的手指和眼睛,不需要javascript,我只是总是添加';'

另一个原因是文档:通过添加';'我明确地对自己说,我希望声明会在哪里结束。然后我也一直都使用{}。

整个字节数参数我觉得很恼人而且毫无意义:

1)适用于jquery之类的常见库:使用google CDN并且该库可能已经在浏览器缓存中了。

2)版本您自己的库,并将其设置为永久缓存。

3)gzip并最小化(如果真的)是必需的。

但是实际上有多少个网站的最大下载速度瓶颈是其javascript的下载速度?如果您为Twitter,Google,Yahoo等排名前100的网站工作。我们其他人应该只担心代码质量而不是分号宗教战争。

评论


我猜相反也可能是正确的。随着python在网络上越来越流行,让您的JS类似于python变得更加容易。

– Ben DeMott
2012年3月31日上午8:37

尝试,但是同一行的字节战士会在我后面追逐不必要的行首空格。 (我还会遇到Javascript错误,因为我将依靠Python的缩进规则而不是使用{}

–帕特
2012年4月1日上午11:21

如果减少字节数很重要,那么您将拥有尽可能减少文件数量的功能。如果还不值得使用最小化器,那么就不必担心删除';'了。以节省字节数。

– Lawtonfogle
15年4月16日在20:07



字节数实际上并不一定要减少,实际上它实际上可以增加,因为换行通常(并非总是)实际上是两个字符(换行后跟回车符),因此以最节省空间的形式该行将一次与一个字符的分号相同(如果将所有JS代码压缩为一行,这通常是针对已部署的JS代码而不是开发源代码完成的)。

– ALXGTV
2015年5月30日17:46



人类需要缩进来理解深度嵌套,深度嵌套比分号需要更多的字节。分号正在分散按键的浪费。

– Cees Timmerman
16年6月7日在11:48

#2 楼

它使方法链接更容易,并且可以提交diffs清理器。

所以,假设我正在使用jQuery,并且具有

$('some fancy selector')
  .addClass()
  .attr();


如果要添加东西,并保持基于行的提交差异较小,我必须将其添加到attr上方。因此,比“最后添加”要花更长的时间。谁想思考? =)

$('some fancy selector')
  .addClass()
  // new method calls must go here
  .attr();


但是,当我删除分号时,我可以追加并命名为一天

  $('some fancy selector')
    .addClass()
    .attr()
+   .animate()
+   .click()


此外,如果我决定退出最后一种方法,则不必重新分配分号并再次污染我的提交。

  $('some fancy selector')
    .addClass()
    .attr()
    .animate()
-   .click()


与uggo相比

  $('some fancy selector')
    .addClass()
    .attr()
+   .animate();
-   .animate()
-   .click();


评论


这是利基用例IMO。

– JBR威尔金森
2012年3月29日22:30

但是有趣的是。

–乔纳森
2012年3月30日11:30

您可以在新行的末尾缩进分号作为起点。然后,您可以根据需要复制并重新排序。这也很好地关闭了连锁店。

– Nux
13年5月11日在17:38

只是我想知道为什么有人会关心提交内容的差异如何整齐吗?通常,人们阅读代码,而不是差异。

–法律
2014年12月3日12:06



@Jules,差异较大的合并意味着合并更有可能成功。

– joeytwiddle
16-2-14在6:09

#3 楼

JavaScript中的半冒号是可选的

我不使用半冒号的个人原因是OCD。

当我使用半冒号时,我忘记了其中的2%,必须经常检查/将它们重新添加。

当我不使用半冒号时,我从来不会无意间插入半冒号,因此我不必检查/移除它们。

评论


好一个我已经在没有其他分号的文件中被一两行无分号的内容灼伤了。

–乔纳森
2012年3月29日在12:59

如果没有分号,解析器(例如GeSHi)将无法正确解析您的代码。您可以说人类不会犯这样的错误……但是,很严重-如果您的所有团队都能够记住绝对需要在何处放置分号,您是否真的会认为没有早上喝咖啡就会记住它?他们将以多种心态进行编码。一定要

– Nux
13年5月11日在17:08

如果这是您的问题,则可以使用lint来检查代码。

– Ruben Verschueren
19年11月22日在9:49

#4 楼


没有信息过载,只有糟糕的设计。

—爱德华·图夫特


图形设计中的一般规则是排除不必要的信息元素和装饰物以减少噪音。

屏幕上较少的视觉元素意味着我们的大脑需要较少的工作来解析实际的有用信息。

let foo = 1


> vs。

let /* variable */ foo = 1; // EOL


当然是一个夸张的示例,但它说明了一般原理:当且仅当它们满足特定目的时,才应添加其他视觉元素。那么,分号是否有目的?

在JavaScript中使用分号的历史原因是:


保持与C / Java的相似性
避免兼容性浏览器和工具编写得不好的问题
帮助人和机器检测代码错误
自动分号插入会降低性能


兼容性问题几乎是非今天发行。现代短毛绒无需分号也可以检测到任何代码错误。与C / Java / PHP的相似性仍然是一个考虑因素(请参见Pat接受的答案),但是仅仅因为其他语言包含多余的语法元素并不意味着我们应该将它们保留在JavaScript中,尤其是由于许多其他语言(咖啡,Python, Ruby,Scala和Lua)不需要它们。

我做了一个快速测试,看看V8是否存在性能损失。这是Io.js解析一个41 MB的JavaScript文件(Lodash重复了100次),然后分号,然后删除了分号:

$ time node lodashx100.js
node lodashx100.js  2.34s user 1.30s system 99% cpu 3.664 total
$ time node lodashx100s.js
node lodashx100s.js  2.34s user 1.15s system 99% cpu 3.521 total


每个人都必须决定自己喜欢的编码风格,但我再也看不到使用分号有任何实质性的好处,因此,为了减少视觉噪音,我已经停止了。

评论


我会反对在负载中省掉不必要的元素的说法,现在必须要做的就是添加可选语法。现在,如果省略,分号已不是很大的精神负担。这是我在Ruby和Scala中遇到的问题。当它变成一连串的呼叫,且呼叫内部都有呼叫时,并且它们都省略了每个括号,这便成为了分崩离析的负担。

– Seamus
16-10-2在16:43

漂亮的答案👏

– Alex Cory
20-05-22在20:49

#5 楼

最近,我为JavaScript编写了一个解析器/分析器,在那里我不得不辛苦地实现ASI,而且我的书架上也有Crockford的JavaScript:The Good Parts的副本,该书主张始终使用分号。意图是好的,但在实践中并不一定总是有帮助。

显然,编写jQuery,zepto等框架的人是JavaScript语法大师,因此他们知道两者之间的区别:

return
{
    status: true
};




return {
    status: true
};


JavaScript功能强大,同时还是初学者的语言,祝你好运。谁在学习for循环是什么。就像向大多数人介绍一种新技能一样,您不想立即解释一些更复杂的事情,因此,您选择对某些事情灌输“货运邪教”的信念,只是为了让他们起步。因此,在教初学者如何编写JavaScript时,您有两种选择:告诉他们“遵循这条规则,不要问为什么”,告诉他们在输入时始终加分号。每行的结尾。不幸的是,这对上面的示例或任何其他妨碍ASI的示例都没有帮助。上面的代码失败后,初学者程序员都会迷惑不解。
告诉他们“遵循这两个规则,不要问为什么”,告诉他们不要在每行的结尾都打分号,并且相反,总是a)在return后面加上{,然后b)当一行以(开头时,在前面加上;

选择选项2是更好的“货物崇拜”规则集跟随(将导致很少的与ASI相关的错误),即使您对主题有深入的了解,屏幕上的不需要字符也会更少。

评论


好吧,我咬。帮助我了解以上两个示例在语法上的区别。我未经训练的眼睛只会看到格式上的差异。

– Jesse C. Slicer
2012年3月29日在20:27

或者,另一方面,由于偶然的意外,我偶然发现了答案。在第一个示例中,返回值被认为是一个单独的语句,而行尾等于一个分号。第二个示例实际上返回了对象。调皮。

– Jesse C. Slicer
2012年3月29日20:30

我不同意JavaScript是一种初学者的语言,在JavaScript中存在大量的不一致之处和令人惊讶的效果,但这些解释并没有简单的解释。 IMO不是初学者的语言,我将JavaScript称为中间语言。

–Ryathal
2012年3月29日20:32

@Ryathal我了解您的意思,但是将其称为中间语言会让我想知道它会中介哪种语言。您听起来好像是迈向其他事物的一步,而不是本身就是目的地。

– Racheet
13年5月13日在16:43

澄清点:返回示例实际上是正常JS行为的一个例外,该行为是在省略分号时尝试将行合并在一起。 return,break和continue都表现出这种特殊的行为,其中尾随换行符始终被解释为语句的结尾。 (来源是Flanagan的“ JavaScript:权威指南” pp25-26)。就我个人而言,我努力实现“最少惊喜的代码”的想法。遗漏分号往往会带来比任何东西都更多的惊喜(即使是简单的陈述,我通常也会大括号)。

–凯尔
13年5月13日在16:58

#6 楼

选择编程约定实际上与选择目标语言的子集相同。我们都这样做是出于通常的原因:代码的可读性,可维护性,稳定性,可移植性等-同时可能会牺牲灵活性。这些原因是真正的业务原因。
诸如“节省键击”和“程序员应学习JavaScript规则”之类的原因都是边际业务原因,因此它们的实用价值很小。

就我而言,我需要非常快地提高JavaScript的速度,因此利用有限的一部分语言对我来说是有利的。因此,我选择了JavaScript的JSLint子集,将Eclipse中的Rockstar应用程序JSLinter设置为我可以承受的最严格的设置,并且没有回头。

我很高兴能够避免“ ==”和“ ===“之间的区别的详细信息,或者分号插入的详细信息,因为我已经有了一个任务高度很高的任务列表,而这些详细信息将无法在一秒钟内完成这些工作。

当然,关于约定的最重要的一点是一致性,将其视为语言的子集有助于加强这一必要性。尽管这可能无法回答OP的问题,但我认为这可能有助于对OP的实际构架。

#7 楼

相当老的问题了,但是我很惊讶没有人提及:

缩小:如果您恰巧缩小了一个未明确用分号字符结束语句的JavaScript代码段,则可能最终很难找出一个片段,该片段在缩小之前是有效的,现在却不起作用。

歧义:分号是可选的,是的,但是通过从源代码中删除它们,您可能会将一些模棱两可的方案留给解析器自行决定。如果您要为网上商店编写100行代码,是的,也许没关系,但是更严重的任务将要求100%的清晰度。

很久以前我读过一篇非常不错的文章打个比方,但在这种情况下也很正确:(在我们的情况下)消除分号就像在红灯处横穿一样。最后您可能会好起来,或者可能被卡车撞上。

为什么现在越来越流行了?

我个人认为让JavaScript在服务器上运行-方面对JavaScript社区本身有很多影响。在我们的例子中,显然没有人会在服务器端缩减JavaScript(因为不应将源代码发送到客户端的Web浏览器),因此没有分号看起来更安全,这是事实。但是,从这些书,文章和视频中学习的其他开发人员,不幸地忽略了服务器端JavaScript与客户端JavaScript不完全相同的事实。

评论


缩小符可以留在单字符换行符中,或者在不存在分号的情况下插入分号而不会造成大小损失。我不知道哪个(如果有的话)缩小器会这样做。至少其中一些仍然存在危险,因此您的观点在实践中仍然成立。

– outis
15年7月12日在23:25

如果一个压缩程序破坏了您的代码,那么该压缩程序就被破坏了,您不应该使用它。

– Jbm
20年5月8日在17:20

#8 楼

将它们保留在里面是有充分的理由的。

它们并不是真正可选的,当它们丢失时,JS可以通过自动分号插入将它们重新添加进去,但这不是同一回事。

道格拉斯·克罗克福德(Douglas Crockford)的JavaScript:The Good Parts在两个不同的场合说这是一个坏主意。自动分号插入会隐藏程序中的错误并造成歧义。

JSLint不赞成。

#9 楼

十多年来,JavaScript不需要分号来终止语句。这是因为换行符被认为是语句终止符(我相信早期的ECMAScript规范中也提到了这一点)。这确实很有意义,尤其是因为[我所知道的]确实没有充分的理由[为什么]为什么JavaScript需要频繁使用分号而不需要其他解释性声明性语言(如Ruby或Python)。

要求使用分号可以简化为一种语言编写解析器的步骤,但是,如果那里的每个解释器都支持省略分号,那到底是什么意思呢?

归结为程序员的知识渊博:如果您知道可以省略分号,请随意这样做,以了解可能有或没有后果。人类是决策机器,几乎所有决策都需要做出一些折衷或权衡。权衡一下,只是在您的代码周围抛出分号(即使在不需要它们的地方),这是因为您的代码变得可读性较低(取决于您问的是谁),并且JSLint不会抱怨(谁在乎) )。另一方面,要舍弃分号的权衡是90%的JavaScript程序员会为之而为,但您可能最终会因此而喜欢编写JavaScript。

听起来对您来说更好;做出明智的决策还是盲目决策/群体心理?

评论


我想知道为什么这收到了反对票。 JavaScript不需要分号来终止语句。它当然可以使用它们,但绝不是必需的。如果需要它们,那么没有其他人的解释会起作用。您可以编写几乎没有分号的整个JavaScript应用程序这一事实(是的,事实)证明了这一点。除此之外,我看不出如何理解工具的工作方式以及如何使用自己的推理来做出决策与“仅仅做到”相反。那就是所谓的宗教。

–拉文斯汀
15年8月27日在23:28

我没有拒绝投票,但问题可能是这实际上不符合书面要求。在JavaScript中,换行符不视为语句终止符。由于称为分号自动插入的功能,您可以省去分号,该功能可让分号在某些情况下自动修复解析错误。提倡分号的人认为,许多JavaScript程序员似乎对这条规则不太了解。从这个角度来看,您的帖子似乎是对他们有利的一个论点。 (公平地说,我大体上同意你的论文,但出于不同的原因)

– Tim Seguine
18年4月26日在21:13

@TimSeguine是的,我回想起之前写了这封信。我仍然认为不使用分号只是客观上的错误,只要这样做的人知道他们在做什么。我应该重做我的帖子,或者因为其他足够多的人对此发表意见,所以应该删除它。感谢您的礼貌批评! :)

–拉文斯汀
18年4月26日在23:21

#10 楼

我有两种理论:

A)

关于这种选择的事情是,在过去,当JSLint等适用时,您选择花费大量资金。捕获模糊语法错误的时间,或在代码上执行标准策略所需的时间。

但是,随着我们朝着单元测试驱动的代码和持续集成的方向发展,时间(和人工)捕获语法错误所需的交互性已大大降低。来自测试的反馈将迅速表明您的代码是否能按预期工作,早在接近最终用户之前,所以为什么要浪费时间添加可选的详细信息?

B)

懒惰的程序员会在短期内做任何事情来使自己的生活更轻松。减少打字->减少精力->更容易。 (另外,不必使用分号也可以避免使右手无名指紧张,避免出现RSI感)。

(注:我不同意省略一些使语句模糊不清的想法)。

评论


jshint仍然是重要的工具。

–雷诺斯
2012年3月29日下午16:40

关于消除歧义,\ n和; \ n相同

–雷诺斯
2012年3月29日在16:41

@Raynos实际上,我发现JSLint在我经常使用的一些框架繁重的代码的复杂性方面似乎毫无用处。另外,; \ n和\ n并非在所有情况下都相同,否则就永远不需要;。

–埃德·詹姆斯(Ed James)
2012年3月29日在16:48

jslint没用,但是jshint是另一种工具。

–雷诺斯
2012年3月29日在17:09

#11 楼

我不会遗漏它们,但是会在插入它们时更改规则。

大多数人使用的规则是


每行结束之前
除了行尾以来自函数语句的}结尾
,但是只有函数语句而不是赋给函数文字

我的规则是:在每一行的开头带有开口撑杆/支架。

矿井更简单,因此更易于跟踪且不易受虫子侵害。另外,分号数量少,可以很容易地找到因遗漏而产生的错误。


另一个说法是臭名昭著的return\nvalue错误源于对ASI的不了解。我的规则会强迫您了解ASI,因此使用我的规则的人不太可能陷入该错误的陷阱。