前端JavaScript基础训练系列一百三十:纠错机制

是否应该完全依赖 ASI 来编码,这是 JavaScript 社区中最具争议性的话题之一(除此之外 还有 Tab 和空格之争)。
大多数情况下,分号并非必不可少,不过 for( … ) … 循环头部的两个分号是必需的。 正方认为 ASI 机制大有裨益,能省略掉那些不必要的 ;,让代码更简洁。

此外,ASI 让许
多 ; 变得可有可无,因此只要代码没问题,有没有 ; 都一样。
反方则认为 ASI 机制问题太多,对于缺乏经验的初学者尤其如此,因为自动插入 ; 会无意 中改变代码的逻辑。还有一些开发人员认为省略分号本身就是错误的,应该通过 linter 这 样的工具来找出这些错误,而不是依赖 JavaScript 引擎来改正错误。

仔细阅读规范就会发现,ASI 实际上是一个“纠错”(error correction)机制。这里的错误 是指解析器错误。换句话说,ASI 的目的在于提高解析器的容错性。
究竟哪些情况需要容错呢?我认为,解析器报错就意味着代码有问题。对 ASI 来说,解析 器报错的唯一原因就是代码中缺失了必要的分号。
我认为在代码中省略那些“不必要的分号”就意味着“这些代码解析器无法解析,但是仍 然可以运行”。
仅仅为了追求“代码的美观”,省去一些键盘输入,这样做不免有点得不偿失。
这与空格和 Tab 之争还不是一回事,后者仅涉及代码的美观问题,前者则关系到原则问 题:是遵循语法规则来编码,还是打规则的擦边球。
换个角度来看,依赖于 ASI 实际上是将换行符当作有意义的“空格”来对待。在一些语言 (如 Python)中空格是有意义的,但这对 JavaScript 是否适用呢?
我建议在所有需要的地方加上分号,将对 ASI 的依赖降到最低。 以上观点并非一家之言。JavaScript 的作者 Brendan Eich 早在 2012 年就说过这样的话

ASI 是一个语法纠错机制。若将换行符当作有意义的字符来对待,就会遇到很多 问题。多希望在 1995 年 5 月的那十天里(ECMAScript 规范制定期间),我让换 行符承载了更多的意义。但切勿认为 ASI 真的会将换行符当作有意义的字符。

错误

JavaScript 不仅有各种类型的运行时错误(TypeError、ReferenceError、SyntaxError 等),
它的语法中也定义了一些编译时错误。 在编译阶段发现的代码错误叫作“早期错误”(early error)。语法错误是早期错误的一种
(如 a = ,)。另外,语法正确但不符合语法规则的情况也存在。 这些错误在代码执行之前是无法用 try…catch 来捕获的,相反,它们还会导致解析 / 编译
失败。
规范没有明确规定浏览器(和开发工具)应该如何处理报错,因此下面的报 错处理(包括错误类型和错误信息)在不同的浏览器中可能会有所不同。
举个简单的例子:正则表达式常量中的语法。这里 JavaScript 语法没有问题,但非法的正 则表达式也会产生早期错误:

var a = /+foo/; // 错误!

语法规定赋值对象必须是一个标识符(identifier,或者 ES6 中的解构表达式),因此下面的

42 会报错: var a;
42 = a; // 错误!

ES5 规范的严格模式定义了很多早期错误。比如在严格模式中,函数的参数不能重名:

     function foo(a,b,a) { }
     function bar(a,b,a) { "use strict"; }
再如,对象常量不能包含多个同名属性:
     (function(){
         "use strict";
// 没问题 // 错误!
var a = { b: 42,
b: 43 })();
// 错误!
};

从语义角度来说,这些错误并非词法错误,而是语法错误,因为它们在词 法上是正确的。只不过由于没有 GrammarError 类型,一些浏览器选择用 SyntaxError 来代替。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值