我在使用js的时候可能发现一个现象:js语句结尾有时候有分号,有时候没有,没有的时候js代码也是能正确执行的。

到底要不要写分号?QAQ

转自博客园@winter-cn

JavaScript自动加分号规则,有3条

  1. 当有换行符(包括含有换行符的多行注释),并且下一个token没法跟前面的语法匹配时,会自动补分号。
  2. 当有}时,如果缺少分号,会补分号
  3. 当程序源代码结束时,如果缺少分号,会补分号。

利用我自己的JS语法分析工具JSinJS(https://github.com/kissjs/JSinJS ),我求出了所有能够出现在语句第一个的JS语法标记 (就是Statement的first集合),他们是:

["debugger", "try", "throw", "switch", "Identifier", "with", "return", "break", "continue", "for", "while", "do", "if", "new", "function", "(", "{", "[", "RegularExpressionLiteral", "StringLiteral", "NumericLiteral", "BooleanLiteral", "NullLiteral", "this", "!", "~", "-", "+", "--", "++", "typeof", "void", "delete", ";", "var"]

共计35个。

我又求出了所有可以出现在分号之前的语法标记(即去掉分号以后的last集),他们是

["--", "++", "IdentifierName", "]", ")", "}", "RegularExpressionLiteral", "StringLiteral", "NumericLiteral", "BooleanLiteral", "NullLiteral", "Identifier", "this", "debugger", "return", "break", "continue"]

共计17个。

35*17 = 595种组合,为了方便记忆,以下我分组来讨论语法歧义 。(本来用Excel弄了张表,不过表太大了不好贴出来)

首先,以下语法标记开头的语句是绝对安全的,不会跟不加分号的上一行产生任何歧义:

var if do while for continue break return with switch throw try debugger ;

接下来我们来分组看不加分号导致的语法歧义:

  • 第一种是++和--两种运算符出现在上一行结尾的情况,下一行以以下开头时,会产生语法歧义:  
    function delete void typeof new null true false NumericLiteral StringLiteral RegularExpressionLiteral ( [ { Identifier ++ -- + - ~ !  
    其中,function和delete是非常常用的statement开头。 
    特别是 ++和--单独被断为一行的时候,因为JS的语法规则规定后自增运算不允许中间插入换行,所以++和--会被视为前自增而跟下一行连接在一起。
  • 第二种是return作为上一行结尾的情况,下一行以以下开头时,会产生语法歧义: 
    function delete void typeof ( [ { Identifier ++ -- + - ~ !

    同样因为JS语法的规则不允许在return 和后面的值之间插入换行,所以return之后只要有换行符就会视为有分号,这常常会与使用者的期望不符合。

  • 第三种是下一行以+和-开头的情况,上一行以以下结尾是,会产生语法歧义: 
    -- ++ IdentifierName ] ) } RegularExpressionLiteral

    因为很少有语句以+或者-开头,所以这种情况不算危险。

  • 第四种是上一行以break、continue结尾的情况,下一行以Identifier开头时,会产生语法歧义。
  • 第五种是下一行以(和[开头的情况,上一行以以下结尾是,会产生语法歧义: 
    -- ++ IdentifierName ] ) } RegularExpressionLiteral StringLiteral NumericLiteral BooleanLiteral NullLiteral Identifier this 
    这种情况非常危险(所以hax的文章中要提出这种情况应该语句前写分号),几乎上一行的所有情况都将导致正常期望之外的结果。 
  • 第六种是,当下一行以RegularExpressionLiteral 开头的情况,上一行的以下结尾,会导致/被理解为除号: 
    -- ++ IdentifierName ] ) }  RegularExpressionLiteral StringLiteral NumericLiteral BooleanLiteral NullLiteral Identifier this

总结,

    1. 在return、break、continue、后自增、后自减五种语句中,换行符可以完全替代分号的作用。

    2. var if do while for continue break return with switch throw try debugger几种关键字开头的语句,以及空语句,上一行加不加分号影响不大。

    3. 凡表达式语句和函数表达式语句,后面不加分号非常危险,情况极其复杂。

    4. 凡(和[开头的语句,前面不加分号极度危险。

看过@winter-cn总结之后,我觉得虽然JavaScript一般情况下可以自动补分号,但是不加分号可能导致语法歧义,出现的不可预料的问题,为了避免因为小小分号引起程序错误,平时写js代码还是有一个好习惯,写上分号!

关于js语句的分号的更多相关文章

  1. 编写js语句结束时保持良好的习惯-源于身边例子

    记录以下信息,源于一件事情,一位同事,每次我改他的js代码,发现语句结束都不使用分号作为结束.长长的一串,读起来比较吃力.即便语句的结束不使用分号结束,代码仍然不会报错,正常运行,所以不少程序员懒得去 ...

  2. h5 录音 自动生成proto Js语句 UglifyJS-- 对你的js做了什么 【原码笔记】-- protobuf.js 与 Long.js 【微信开发】-- 发送模板消息 能编程与会编程 vue2入坑随记(二) -- 自定义动态组件 微信上传图片

    得益于前辈的分享,做了一个h5录音的demo.效果图如下: 点击开始录音会先弹出确认框: 首次确认允许后,再次录音不需要再确认,但如果用户点击禁止,则无法录音: 点击发送 将录音内容发送到对话框中.点 ...

  3. JS 语句

    JS 语句 JavaScript 语句 JavaScript 语句向浏览器发出的命令.语句的作用是告诉浏览器该做什么. 下面的 JavaScript 语句向 id="demo" 的 ...

  4. 通过JS语句判断WEB网站的访问端是电脑还是手机

    通过JS语句判断WEB网站的访问端是电脑还是手机,以显示不同的页面! 目录腾讯网的适配代码如何判断访问网站的机器类型-如何判断ipadJS 判断浏览器客户端类型(ipad,iphone,android ...

  5. 浅谈 js 语句块与标签

    原文:浅谈 js 语句块与标签 语句块是什么?其实就是用 {} 包裹的一些js代码而已,当然语句块不能独立作用域.可以详细参见这里<MDN block> 也许很多人第一印象 {} 不是对象 ...

  6. JS语句

    JS语句包括: 1.顺序语句 2.分支语句:  if...else                   switch...case 3.循环语句 一.先看顺序语句: </body> < ...

  7. c-lodop云打印实现手机打印 JS语句打印

    Lodop和c-lodop目前只能安装到windows操作系统上,但是其他操作系统可通过向C-Lodop安装的电脑发送打印任务,实现手机广域网或局域网打印,打印语句也是简单的JS语句,可以轻松实现云打 ...

  8. legend---十二、js中的js语句和函数和ready函数的关系是什么

    legend---十二.js中的js语句和函数和ready函数的关系是什么 一.总结 一句话总结: 函数和全局变量不必放到ready函数中 语句(调用函数和全局变量)的必须放到ready函数中 1.在 ...

  9. mybatis中的map.xml文件中sql语句需要分号吗?

    mybatis中的map.xml文件中sql语句需要分号吗? :你是说sql介绍的分号吗?不需要的

随机推荐

  1. 记录一下ionic canvas图片,还有canvas里面的图片跨域的问题

    import { Component, Inject, forwardRef } from '@angular/core'; import { IonicPage, NavController, Na ...

  2. php之函数

    scope(空间) unpack (解压) Traversable (穿越) performance(性能) experiment (检验) properties (属性) trailing (尾随) ...

  3. 中文乱码与字体库windows

    设置中文后,查看图形有乱码,文字变成了方块 Win+R打开运行,输入fonts,回车进入Windows字体目录,找到微软雅黑-常规字体,复制出来将文件名修改为msyh.ttf,注意后缀ttf. 将ms ...

  4. [development][dpdk] dpdk-pmdinfo 工具的使用

    发现了一个工具 dpdk-pmdinfo 但是文档介绍的很不清楚, http://dpdk.org/doc/guides/tools/pmdinfo.html 经过摸索, 这可能就是一个查询 dpdk ...

  5. 阿里创新自动化测试工具平台--Doom

    摘要: 阿里内部诞生一了个依赖真实流量用于自动回归的自动化测试平台,通过创新的自动mock机制不仅支持读接口的回归验证,同时支持了写接口验证,在内部产生了极大价值,有价值的东西就应该分享,目前该工具已 ...

  6. ORACLE INSTANCE与EM系统

    Emctl start dbconsole https://192.168.183.132:1158/em/ 复制到游览器进入到em 更改初始化参数值 静态参数: -只能在参数文件中更改 -必须重新启 ...

  7. Win10系统桌面右键新建没有内容怎么恢复

    Win10系统桌面右键新建没有内容怎么恢复 添加txt文本文档 运行->regedit,打开注册表编辑器 展开HKEY_CLASSES_ROOT 找到.txt 选中.txt,修改右侧窗格的“默认 ...

  8. scrapy windows下出现importError:No module named 'win32api'

    scrapy windows下出现importError:No module named 'win32api'需安装 pip install pypiwin32

  9. SQL查询优化:详解SQL Server非聚集索引(转载)

    本文是转载,原文地址 http://tech.it168.com/a2011/1228/1295/000001295176.shtml 在SQL SERVER中,非聚集索引其实可以看作是一个含有聚集索 ...

  10. 在同一台电脑上部署多个tomcat服务器

    因为在写一些小的项目的时候,需要另外用到一台图片服务器,所以不得不开启多个tomcat了. 在这里我用的是tomcat 9.0,一个是正常时的tomcat,一个是图片服务器,在这里我就用tomcat1 ...