聊聊 JavaScript 的 ASI 机制

官方文档

ASI ,automatic semicolon insertion,自动分号插入机制,它是一种程序解析技术 ,它在 JavaScript 程序的语法分析(parsing)阶段起作用。

根据 ES6 规范,某些 JS 语句需要用;来表示语言结束,而某些情况下;可以从源码中省去且不会报错,此时我们可以认为;被 parser 自动插入到符号流 当中去了(这只是形象上的比喻,并没有真实发生,代表编译器在没有分号的情况下也正确理解了程序员的意图),这种机制称为 ASI

🌟行结束符

CR -- 回车 --> \r

LF -- 换行 --> \n

编辑器不会优先 启用 ASI 机制,在遇到行结束符时,编辑器总是试图将行结束符分隔的语句当成同一条语句来解析(有特例),实在不符合正确语法的情况下就会退而求其次,启用 ASI 机制,将分隔的语句当成两条语句处理。比如:

javascript 复制代码
var a = 1
var b = 2
// 此代码段的符号流为  var a = 1  \n  var b = 2

// parser 从左到右解析这个符号流
var a = 1  var b = 2	// Uncaught SyntaxError:Unexpected token 'var'

// 于是报错了,不甘心的 parser 启用 ASI 再次尝试
var a = 1; var b = 2   // 没有报错,解析通过

需要注意的是 JS 中存在几个"脆弱符号",可能导致在 parser 解析符号流的时候误解程序的意图。

"脆弱符号"有:[(/+-

javascript 复制代码
var num = 5
+new Date() - new Date(2009, 10)
// 此代码段的符号流为 var num = 5  \n  +new Date() - new Date(2009, 10)

// parser 从左到右解析这个符号流
var num = 5 + new Date() - new Date(2009, 10)	// 由于 + 有二义性,所以没有语法错误
// 程序意图被曲解

处理这类情况的办法是,在"脆弱符号"前面显式地加上防御性分号

按理说,ASI 是一种备用选择 ,然而 ECMAScript 中,有几种特殊语句是不允许 行结束符存在的,如果这种特殊语句有行结束符,parser 会优先认为行结束符表示语句结束,这时 ASI 不再是候选机制,而是优先启动

特殊语句:return语句、块语句、空语句、continue语句、break语句、throw语句、箭头函数、yield表达式、后自增/自减表达式。

javascript 复制代码
function a() {
	return
    {};
}
a()	  // undefined

// 本来,parser 解析后应该是这样的
function a() {
	return {};
}
a()	   // {} (empty object)

// 实际输出并不符合预期,因为解析结果实际上是这样的
function a() {
	return;
    {}
    ;
}
a()
// 函数体内的代码被解析成了 return 语句、块语句和空语句三条单独的语句

有备用开启 ASI 的,有优先开启 ASI 的,也有不会开启 ASI 的情况。

那就是for循环语句,for循环语句头部的 3 个条件语句必须 有分号隔开,不然 parser 不会自动添加


写在最后

One day you'll leave this world behind. So live a life you will remember! --- Avicii

我是暮星,一枚有志于在前端领域证道的攻城狮。

优质前端内容持续输出中......,欢迎点赞 + 关注 + 收藏

相关推荐
北海-cherish2 小时前
vue中的 watchEffect、watchAsyncEffect、watchPostEffect的区别
前端·javascript·vue.js
AALoveTouch3 小时前
网球馆自动预约系统的反调试
javascript·网络
2501_915909063 小时前
HTML5 与 HTTPS,页面能力、必要性、常见问题与实战排查
前端·ios·小程序·https·uni-app·iphone·html5
white-persist4 小时前
Python实例方法与Python类的构造方法全解析
开发语言·前端·python·原型模式
新中地GIS开发老师5 小时前
Cesium 军事标绘入门:用 Cesium-Plot-JS 快速实现标绘功能
前端·javascript·arcgis·cesium·gis开发·地理信息科学
Superxpang5 小时前
前端性能优化
前端·javascript·vue.js·性能优化
左手吻左脸。5 小时前
解决el-select因为弹出层层级问题,不展示下拉选
javascript·vue.js·elementui
李白的故乡5 小时前
el-tree-select名字
javascript·vue.js·ecmascript
Rysxt_5 小时前
Element Plus 入门教程:从零开始构建 Vue 3 界面
前端·javascript·vue.js
隐含5 小时前
对于el-table中自定义表头中添加el-popover会弹出两个的解决方案,分别针对固定列和非固定列来隐藏最后一个浮框。
前端·javascript·vue.js