前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >写给前端专家的一封公开信:关于分号(翻译)

写给前端专家的一封公开信:关于分号(翻译)

作者头像
IMWeb前端团队
发布2019-12-03 17:59:40
4960
发布2019-12-03 17:59:40
举报
文章被收录于专栏:IMWeb前端团队IMWeb前端团队

本文作者:IMWeb frankfang 原文出处:IMWeb社区 未经同意,禁止转载

原文

Sean Silva 给我发来一封信:

我最近在浏览你 npm.js 项目里的代码(代码链接),很喜欢你的代码风格: 你把逗号放在行首,与上一行 var 中的 r 对齐,或者与上一行的 [{ 对齐。但是我不是很敢学的你风格,因为很多 JS 教材都说 JS 解释器的自动加分号机制会对代码有影响。 如果我不把逗号放在行尾,而是放在下一行行首,在浏览器里是否安全呢?抑或是说只能在 Node 里这样用呢? 2011年11月20日

我回复道:

是的,这样是安全的,而且是完全合法的 JS,每个浏览器都理解。Closure、yuicompressor、packer 和 jsmin 都可以完美地压缩这样的 JS。而且也不存在性能影响。 遗憾的是,前端社区的一些专家散布谎言和恐惧,却没有真正地指导新人。我推荐新人去了解 JS 语句是到底是怎么「断句」的,那样才能写出自己认为优美的代码。

Inimino 的文章《JS 分号必知必会》对此解释得很清楚,他本人对是否添加分号持保留意见,但我打算更主观一些。

规则

一般地,\n 表示一个语句结束,除非出现下面几种情况:

  1. 该语句中含有未关闭的([、或 {,或者是以某种不合法的结束方式来结束(如以 . 或者 , 结束)
  2. 这一行的内容是 --++(这会使下面一行自增或自减)
  3. 这一行是 for() while() do if()else 等语句,且不带 {
  4. 下一行以 [ ( + * / - , . 或其他二元操作符开头

第一条是很显然的事情。我们在 JSON 里经常用到类似的断句方式,在一个 var 语句里声明多个变量时也会用 , 来断句。

第二条就比较奇怪。假设我们写 i\n++\nj,结果得到的是 i; ++j,却不是 i++; j

第三条很好理解。if (x)\n y() 会被认为是 if (x) {y()}

第四条是我们恐惧的诱因:「不行,你一定要加上分号,不然下一行的二元操作符会引发问题的!」但是,如果下一行不想影响上一行,只要在行首加一个分号就能解决问题。比如

代码语言:javascript
复制
foo();
[1,2,3].forEach(bar);

可以写成

代码语言:javascript
复制
foo()
;[1,2,3].forEach(bar)

这样写的好处是行首分号更容易引起注意,而且你会习惯于在以 ([ 开头的语句前面加上分号。

Restricted Productions(受限操作)

另一个争论点是关于 Restricted Productions。如果你在 return throw break continue ++-- 后面加一个 \n,那么语句就立即结束。

代码语言:javascript
复制
// 预期
return 7
// 产生错误
return
        7

我必须再一次强调,在你改变了「在一切语句后面加分号」的习惯后,这种问题是非常容易发现和避免的。当我看见 return\n,我的大脑会立刻告诉我「这条语句已经结束了」,因为 \n 就是语句结束标记。

把相关标记放在每行行首是最适合人类快速阅读的。大量与阅读速度和眼球跟踪的研究已经说明,在每行行尾找出一个缺少的字符比在行首找难得多。所以我说,应该把重要的标记放在行首。

哪一种风格更好?

目前而言,我认为「尽量少些分号,逗号放在行首」(minimal-semicolon/comma-first)的风格略微优雅一些。不仅因为它更适合人类扫读,而且它还鼓励程序员深入了解他们所用的语言。

其实你大可不必关心我的代码风格是怎样的,反正我不关心你的代码风格是怎样的。这篇文章不是让你模仿我的代码风格,毕竟「你自己的代码只有你自己最了解」。

在所有语句后面加分号的好理由

加分号最靠谱的理由是

  • 美观:如果你写很多 Java 或 C 代码,同时不想让你的 JavaScript代码显得很不一样,那么你可以这样做。
  • 规范:如果为了团队代码的一致性,比如统一采用了 JSHint,那么也可以这样做。

糟糕的理由

「自动加分号(ASI)不靠谱。」

真的吗?

这话在 JavaScript发展的早期,也就是 90 年代,就有很多人说。在我看来这种自称 JavaScript专家却对 JS 断句机制不了解的人是不可原谅的,像他们这样散布未经证实的观点也是极不负责任的。

而且,他们所谓不靠谱都与 Restricted Productions 有关,在所有地方加分号只会让 return\n7 变成 return;7;,真正的问题在于你乱加回车,而不是分号。

唯一的解决办法是别用回车(\n),全部都用分号。(译注:那岂不是所有代码都在一行了。)但是不会有人建议这样做。所以不要再拿 return 的例子来说自动加分号的坏话了,如果你不了解 ASI 的话你就承认自己在滥用分号就好了。你只有在了解了 ASI 之后才有资格说自己是一个 JavaScript开发者,就这样。

一些主观的、可能会冒犯你的话

如果你不了解 JS 的断句机制,那么你就对 JS 掌握的不太好,也不应该在没有指导的情况下写 JS,而且你也不应该指导任何人写 JS。

我猜我已经冒犯到你了。很不幸,虽然我知道你可能已经掌握了 JS 周边的很多知识,比如 DOM,比如 CSS,比如 IE 的兼容技巧,还有 jQuery。可能你也已经花了一些时间学习闭包、原型、作用域和活动对象,甚至还给 V8 和 SpiderMonkey 写过扩展。我知道你很聪明,或许比我聪明多了,也比我帅,说不定我们有很多共同点,还能成为朋友。

但是,如果你不是真正的了解 JavaScript语句,那么你对这门语言的了解就存在一个短板。

(译注:后面太主观了,就不翻译了)

(完)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-06-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 规则
  • Restricted Productions(受限操作)
  • 哪一种风格更好?
  • 在所有语句后面加分号的好理由
  • 糟糕的理由
  • 一些主观的、可能会冒犯你的话
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档