JavaScript 自动插入分号

JavaScript 自动插入分号

本文介绍了自动插入分号机制在return语句中的例子,以及在es5标准下的相应规则。

楔子

之前一直写C,写了一段时间JavaScript之后一直很很好奇一个东西。在C和Java等语言里面,大括号的使用一般都是类似这样的

int main(args[])
{
    return 0;
}

而到JavaScript里面则是这样写

function main(args){
    alert("hello");
    return 0;
}

起始的大括号不独占一行了,觉得很疑惑,查了一些资料才知道,这是和JavaScript一个自动修复机制有关系,它总是希望通过自动插入分号来修正有缺损的程序,虽然我不知道这有什么用。

自动插入分号机制

在《JavaScript语言精粹》这本书里,这个机制被划入到了JavaScript的毒瘤里面,与之并列的前面的全局变量。

有些时候,不合时宜地插入分号,会在例如return语句里面导致严重的后果。
如果一个return语句要正确返回一个值,这个值的表达式的开始部分必须和return位于同一行。

我们来看下面这个例子

return
{
    status:true;
}

看起来这是要返回一个包含对象,但是万恶的自动插入分号处理后,返回值变成了undefined,而且不会报任何的错误和警告。
如果我们把大括号这样处理的话就能避免这个问题

return{
    status:true;
};

自动插入分号的详细规则

在es5标准中定义了自动分号插入规则,包括以下三个基本规则加上两个前置条件。

前置条件

1.如果插入分号后解析结果是空语句,那么不会自动插入分号。
例子:

if(i>j)
else k=l

这种情况下,if后面else前面是被解析为空语句,所以不加分号
2.如果插入分号后,它会成为for语句头部的两个分号之一,那么也不会插入分号
例如:

for(a;b
)

这种情况下,虽然分行了,但是不会被插入分号。

基本规则

从左向右解析程序的时候,当遇到一个不符合任何语法产生式的token也就是违规标记的时候,那么只要满足下列条件之一,就会在哪个标记之前自动插入一个分号
1、前一个标记和这个违规标记之前至少存在一个行终止符
2、违规的标记是 }

举个栗子

{1
    2}3
{1
    ;2;}3

在第一行和第二行的1、2不符合任何产生式,且它们之间有一个行终止符,所以会在数字2之前加分号,在第二行2后面也需要加一个分号,因为后面的违规标记是一个}

左到右解析程序,tokens 输入流已经结束,当解析器无法将输入 token 流解析成单个完整 ECMAScript 程序 ,那么就在输入流的结束位置自动插入分号。

对于受限产生式,也就是下面的5个,我们把产生式 后面的 token 叫做受限 token,如果在 token 和 受限 token 间存在了至少一个行终止符,那么会在受限 token 前自动加上 token。

受限的产生式只限如下5个:

后缀表达式continue语句break语句return语句throw语句

如何预防这个毒瘤

1、后缀运算符 ++-- 和它的操作数应该出现在同一行。
2、returnthrow语句的表达式开始位置应该和 returnthrow token 同一行。
3、breakcontinue 语句的标示符应该和 breakcontinuetoken 同一行。

最重要的还是多加分号

来自leviscar的小贴士
为啥只执行函数前面要加分号?
例如我之前看到的zepto.js的源码开头

;(function(undefined) {
  if (String.prototype.trim === undefined) // fix for iOS 3.2
  String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, '')
  }

主要是应对代码合并压缩时,由于缺少分号;带来的错误。知道了上面的规则,在 ( 开头的行前加分号就可以避免错误了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值