今天发现js自动分号补齐的坑,来看如下两段代码:

function Hello(){return{name: ’JavaScript’};
}alert(Hello());//输出undefined

  

function Hello(){return{name: ’JavaScript’};
}alert(Hello());//输出 [object Object]

  略看代码,差不多,但是输出却不一样。仔细看看第一段代码return后面多了个换行。我们平时写后端代码也经常有会这样换行后花括号左对齐的写法。但是在js这里这样写却有不同的输出。这种机制叫分号自动补齐机制( auto semicolon insertion,简称ASI )。

  知乎上有大神关于这个机制的解释:

链接:https://www.zhihu.com/question/21076930/answer/17135846

在ASI的机制中有一类语句叫做restricted productions(不知道中文叫啥)。简单来说,就是组成这类语句的两个token当中不允许出现换行符 \n。如果在第一个token后面遇到了换行符,则判断语句结束,插入分号。restricted productions包括:

  • return xxx (xxx是要返回的对象)
  • throw xxx(xxx是要抛出的错误对象)
  • break / continue xxx(xxx是循环的标签)
  • 作为后缀的 ++ / --

其中前几个关键词还是挺容易记的,最后一条的原因是需要区分以下情况:

a
++
b

因为++/--既可以作为前缀又可以作为后缀,在这样的情况下作为后缀解析会遇上换行符,所以只能作为b的前缀,自动插入分号后变成:

a; ++b;

回到原题,Douglas Crockford认为 { 应该写在行尾,是为了避免换行符导致return直接返回undefined。

篇外:关于分号 ------------------------------------------------------------------------------------------------

很多人觉得ASI坑太多了所以提倡永远手动加分号,这样就不用费心去研究ASI的规则了。但事实上,即使永远手动加分号,你依然会被restricted productions这条规则坑,因为它是在你不想要分号的地方给你插入分号。所以不管你喜不喜欢分号,都最好花点时间好好了解一下ASI的规则。而一旦你知道了ASI所有的坑,不写分号其实是很简单的。

ASI真正需要注意的坑只有两个,restricted productions是其一,另一个就是当下一行开头是 ( [ / 这三个字符之一的时候:

a = b
(function () { ... }())

会被解析成

a = b(function () {...}());

换言之,( ) 会被看做是在调用函数b。同理,[ ] 会被看做是在获取b的属性,而被斜杠坑的情况则要求更苛刻一些:

a = b
/Error/i.test(str) && doSomething()

第二行的写法本身比较少见,但也不是不可能。结果会被解析成:

a = b / Error / i.test(str) && doSomething();

斜杠被解析成了除号!

要躲开这个坑,其实真的挺简单,只要尽量别用这三个字符作为一行开头就行了。事实上遇到比较多的也只有括号开头。真的避不开的话,可以在行头手动加个分号:

a = b
;(function () { ... }())

额外的一点是在for循环声明里面的分号是永远不能省的,ASI不会在for循环声明中插分号,但一般正常人不会把for的声明分三行写吧...

每次我看到 “javascript分号坑很多,所以应该永远加分号” 这样的说法总是有些不屑的,因为永远加分号并不是避免错误的办法,搞懂ASI是怎么回事才是。只要理解了这里说的两个坑,javascript里99%的分号都是不必要的。

  

转载于:https://www.cnblogs.com/zhangcybb/p/7018576.html

auto semicolon insertion 自动分号补齐的坑相关推荐

  1. [翻译]JavaScript秘密花园 - Type Casting,undefined,eval,setTimeout,Auto Semicolon Insertion - 全部完成PDF打包下载

    JavaScript Garden - 原文 JavaScript Garden - 中文翻译 PDF打包下载 类型转换 JavaScript 是弱类型语言,所以会在任何可能的情况下应用强制类型转换. ...

  2. linux快捷命令补齐,Linux Shell简介——自动补齐/命令行的历史记录/编辑命令行/可用的 Shell 快捷方式.doc...

    Linux Shell简介--自动补齐/命令行的历史记录/编辑命令行/可用的 Shell 快捷方式 Unix (及后继者 Linux)在命令行下面诞生,因此,Unix 中的命令行有许多非常实用的功能. ...

  3. ios-晋级之路 CocoaPods引用第三方库不import不自动补齐

    对于CocoaPods不自动补齐解决方案如下 选择工程的 Target -> Build Settings 菜单,找到\"User Header Search Paths\" ...

  4. mysql 自动补齐 表名,列名 方法, 重启mysql方法

    1.mysql自动补齐方法 方法一.修改my.cnf vi /etc/my.cnf [mysql] auto-rehash         #添加auto-rehash 注:修改 #no-auto-r ...

  5. Geany 代码自动补齐功能设置

    很多人用 geany 感觉不方便,有一部分就是相比于 pycham 的自动补齐功能不好使. 现在给大家看下自动补齐功能设置方法,设置完后用起来非常方便哦. Geany 代码自动补全设置: 默认出现自动 ...

  6. Jupyter 编写python代码实现代码自动补齐功能设置实例演示

    Jupyter 代码自动补齐功能 第一章:启用代码自动补齐功能 ① 安装工具包 ② 重启 Jupyter 服务 ③ 功能设置 ④ 效果展示 ⑤ cmd 安装工具包详细过程展示 第一章:启用代码自动补齐 ...

  7. sql server 语句自动补齐

    sql2008 sql语句自动补齐功能 sql2008的命令自动补齐功能在哪设置 包括查询的表明自动补齐 不想用插件 这个好像2008自带的有这个功能 难道我装的版本不对 楼主说的是自动联想功能吧,任 ...

  8. 如何设置使windows(dos)命令中目录和文件可以自动完成和补齐

    1. 如果只是临时使用,可以用cmd /f打开命令窗口 2.如果想永久使用 1)在运行窗口输入regedit 2)找到键值HKEY_LOCAL_MACHINE/Software/Microsoft/C ...

  9. 输入框限制只能输入数字,正数、负数、0,最多两位小数;数字输入框可以输入负数,并最多保留两位小数;el-number-input去掉四舍五入和自动补齐小数;

    场景: –要求1:输入框只能输入数字,可以使正数.负数.0,小数点最多保留两位. –要求2:不需要自动补齐小数点,也不需要自动四舍五入. element-ui的数字输入框el-input-number ...

  10. 【转】Emacs -- 自动补齐

    1. Emacs 自带的hippie-expand (参考的是王垠的) hippie-expand是 Emacs 自带的功能, 把M-/ 绑定到 hippie-expand,在.emacs文件中加入 ...

最新文章

  1. this.options[selectedIndex]的使用
  2. C++从键盘读取字符
  3. webstorm github怎么用_前端开发神器WebStorm发布最新版本2019.3,代码完成更加智能...
  4. 汇编语言 ADC指令和SBB指令
  5. 图解OpenLayers-2.13.1入门实例
  6. Linux疑难杂症解决方案100篇(十)-uptime命令查看linux系统负载
  7. linux 内核 hrtimer,hrtimer在Linux内核中重复任务
  8. 又一数据库高危漏洞爆出,数据安全如何有效保障?
  9. ISE_FIFO_IP核接口测试(一)
  10. 开发WCF/Silverlight须知
  11. Python网络编程之基于socket实现文件上传
  12. 震惊,线程共享变量使用不当引发血案
  13. 光耦p621引脚图_p421光耦引脚图和代换
  14. matlab逆变换法产生随机数_用matlab产生随机数
  15. LSV又新增13个地质图!量测对比分析全都能搞定
  16. RabbitMQ 中的 VirtualHost 该如何理解
  17. 全国计算机access二级真题,最新全国计算机二级access历年真题.doc
  18. vue中用echarts 绘制geo 中国地图
  19. 海通股票交易系统通道接口错误怎么办
  20. ajax提交,form表单提交,onsubmit=return checksubmit()提交验证

热门文章

  1. Windows子系统(GUI)
  2. mysql建立全文索引
  3. [转]库存那些事儿_8_盘点
  4. arcgis地理配准
  5. ECCV 2022 | 石溪大学联合小鹏汽车提出先验知识指导的无监督领域自适应
  6. [转]深邃之思想,纯粹之灵魂——我所了解的柳智宇学长
  7. 深度解读|盘扣销售价格上涨背后的原因是什么?
  8. 2021年下半年软件设计师上午真题答案及解析(三)
  9. 微信支付功能测试用例
  10. Ubuntu关机(shut down)(power off)后不断电的问题