读书频道 > web开发 > Javascript > Effective JavaScript:编写高质量JavaScript代码的68个有效方法
第6条:了解分号插入的局限
2013-12-07 14:11:28     我来说两句 
收藏    我要投稿   
本书共分为7章,分别涵盖JavaScript的不同主题。第1章主要讲述最基本的主题,如版本、类型转换要点、运算符注意事项和分号局限等。第2章主要讲解变量作用域,介绍此方面的一些基本概念,以及一些最佳实践经验。第  立即去当当网订购

JavaScript的一个便利是能够离开语句结束分号工作。删除分号后,结果变得轻量而优雅。

 

上面的代码能工作多亏JavaScript的自动分号插入(automatic semicolon insertion)技术,它是一种程序解析技术。它能推断出某些上下文中省略的分号,然后有效地自动地将分号“插入”到程序中。ECMAScript标准细心地制定了分号插入机制,因此,可选分号可以在不同的JavaScript引擎之间移植。

但是同第3条和第5条的隐式强制转换一样,分号插入也有其陷阱,你根本不能避免学习其规则。即使你从来不省略分号,受分号插入的影响,JavaScript语法也有一些额外的限制。好消息是,一旦你学会分号插入的规则,你会发现你能从删除不必要的分号的痛苦中解脱出来。

分号插入的第一条规则:

分号仅在}标记之前、一个或多个换行之后和程序输入的结尾被插入。

换句话说,你只能在一行、一个代码块和一段程序结束的地方省略分号。因此,下面的函数定义是合法的。


 

解析有误。

这条规则有一个不幸的影响:你总是要注意下一条语句的开始,从而发现你是否能合法地省略分号。如果某条语句的下一行的初始标记不能被解析为一个语句的延续,那么,你不能省略该条语句的分号。

有5个明确有问题的字符需要密切注意:(、 [、 +、 -、 和 /。每一个字符都能作为一个表达式运算符或者一条语句的前缀,这依赖于具体上下文。因此,要小心提防那些以表达式结束的语句,就像上面的赋值语句一样。如果下一行以这5个有问题的字符之一开始,那么不会插入分号。到目前为止,最常见的情况是以一个括号开始,就像上面的例子。另一种常见的情况是数组字面量。


 

即使把var语句提前,这两段程序也应该是等价的(变量作用域的详细信息,请参见第12条),但事实是,b后面跟着一个括号,程序被错误地解析为:


 

结果是:省略语句的分号不仅需要当心当前文件的下一个标记,而且还需要当心脚本连接后可能出现在语句之后的任一标记。类似上述方法,你可以防御性地为每个文件前缀一个额外的分号以保护脚本免受粗心连接的影响。如果文件最开始的语句以这5个脆弱的字符(、[、+、-和 /开头,你就应该这么做。


 

当然,如果脚本连接程序能够自动地在文件之间增加额外的分号是更好的。但并不是所有的脚本连接工具都写得很好,因此,最安全的选择是防御性地增加分号。

此时,你可能会认为,“这是多余的担心。我从来就不省略分号,我会没事儿的。”事实并不是这样。也有一些情况,尽管不会出现解析错误,JavaScript仍会强制地插入分号。这就是所谓的JavaScript语法限制产生式(restricted production),它不允许在两个字符之间出现换行。最危险的情况是return语句,在return关键字和其可选参数之间一定不能包含换行符。因此,语句


 

换句话说,return关键字后的换行会强制自动地插入分号。该段代码被解析为不带参数的return语句,后接一个空的代码块和一条空语句。其他的限制产生式包括:

throw语句

带有显式标签的break或continue语句

后置自增或自减运算符

最后一条规则是为了消除如下代码的歧义:

 

因为自增运算符既可以作为前置运算符也可以作为后置运算符,但是,后者不能出现在换行之前。这段代码被解析为:

 

第三条也是最后一条分号插入规则:

分号不会作为分隔符在for循环空语句的头部被自动插入。

这就意味着你必须在for循环头部显式地包含分号。否则,类似下面的代码

 

将会导致解析错误。空循环体的while循环同样也需要显式的分号。否则,省略分号也会导致解析错误:


 

 提示

仅在“} ”标记之前、一行的结束和程序的结束处推导分号。

仅在紧接着的标记不能被解析的时候推导分号。

在以(、[、+、-或/字符开头的语句前绝不能省略分号。

当脚本连接的时候,在脚本之间显式地插入分号。

在return、throw、break、continue、++或--的参数之前绝不能换行。

分号不能作为for循环的头部或空语句的分隔符而被推导出。

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:第5条:避免对混合类型使用==运算符
下一篇:第7条:视字符串为16位的代码单元序列
相关文章
图文推荐
3.12 本章小结
3.10 添加新函数
3.9 递归
3.8 闭包
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站