[Day10] ASI - 自动插入分号

ASI (Automatic Semicolon Insertion)

ASI 是 JavaScript 自动插入分号的机制,当 JavaScript 语句没有加上分号时,则会受到自动插入分号 (ASI) 规则影响

常见 ASI 规则

以下是几种常见 ASI 规则:

范例1

当执行 continue、break、return... 语句,语句後会自动加上分号

function fn() {
    return
    '我是第一名'
}
console.log(fn()) // undefined

实际运行:

function fn() {
    return; '我是第一名';
}
console.log(fn());  // undefined

修正後:

function fn() {
    return '我是第一名';
}
console.log(fn());  // 我是第一名

范例2

当 JavaScript 语句'後一行'接到'前一行'会发生语法错误时,会自动加上分号

此例中虽未使用大括号包裹 if else 语句,但 ASI 有正确在每行结尾将分号加上

if (1>2) a=1
else a=2
console.log(a) // 2

实际运行:

if (1>2) a=1;
else a=2;
console.log(a); // 2

错误范例1

若将 else 移至与 if 同一行,因 else 并未与 if 做分隔,则会出现执行上的错误讯息

if (1>2) a=1 else a=2
console.log(a)

// Uncaught SyntaxError: Unexpected token 'else'

错误范例2

若改将 console.log 移至与 else 同一行,因 else 并未与 console.log 做分隔,所以也会出现错误讯息

if (1>2) a=1
else a=2 console.log(a)

// Uncaught SyntaxError: Unexpected identifier

正确范例

所以若要放置在同一行,使之正确执行,就要加入分号

if (1>2) a=1; else a=2; console.log(a);
// 2

不发生 ASI 规则,所造成的错误

1. 当新的一行是 ([/ 开始

范例1

新的一行是 ( 开始,不发生 ASI 规则,所以 2 个立即函式并没有隔开,故出现错误

(function () {
    console.log('我是第一名')
}())

(function () {
    console.log('我是第一名')
}())

// 我是第一名
// 我是第一名
// Uncaught TypeError: (intermediate value)(...) is not a function

修正范例1

可以 在立即函式後添加分号在立即函式前添加分号 皆可修正错误

// 方法1

(function () {
    console.log('我是第一名')
}());
(function () {
    console.log('我是第一名')
}());

// 方法2

;(function () {
    console.log('我是第一名')
}())
;(function () {
    console.log('我是第一名')
}())

范例2

新的一行是 ( 开始,不发生 ASI 规则,第三行与第二行并在一起,解释为 函式a 带入参数 a+b,但 a 并不是函式所以出现错误讯息。

var a = 1
var b = a
(a + b).toString()
// Uncaught TypeError: a is not a function
实际运作
var a = 1;
var b = a(a + b).toString();
// Uncaught TypeError: a is not a function

范例3

此例中 /,会被解释成运算符,而非正规表达式,所以错误讯息显示 / 运算符前多了 .

var a = 1
var b = a
/test/.test(b)
// Uncaught SyntaxError: Unexpected token '.'
实际运作
var a = 1;
var b = a/test/.test(b);
// Uncaught SyntaxError: Unexpected token '.'

修正後
var a = 1;
var b = a;
/test/.test(b);

2. 新的一行以 +-*% 开始

范例

新的一行以 + 开始,不发生 ASI 规则并入上一行

var a = 2
var b = a
+a
console.log(a, b) // 2 4
实际运作
var a = 2;
var b = a+a;
console.log(a, b); // 2 4

修正後
var a = 2;
var b = a;
+a;
console.log(a, b); // 2 2

3. 新的一行以 ,. 开始

范例1

新的一行以 , 开始,不发生 ASI 规则并入上一行,所以 变数 b 转为字串

var a = 2
var b = a
.toString()
console.log(typeof a, typeof b) // number string
实际运作
var a = 2;
var b = a.toString();
console.log(typeof a, typeof b); // number string

范例2

新的一行以 , 开始,不发生 ASI 规则并入上一行,所以 变数 b 一样有被 var 宣告

var a = 1
,b = 2

console.log(a, b) // 1 2
实际运作
var a = 1, b = 2;
console.log(a, b); // 1 2

参考文献

六角学院 - JavaScript 核心篇

MDN - 自动分号补全


<<:  【把玩Azure DevOps】Day13 Pipeline与Artifacts应用:Build nuget package上传到Private nuget

>>:  11 | WordPress 传统区块 Classic Block

Day9 You have to trust that the dots will somehow connect in your future

Plotting regression line 继昨天画出XY关系图後,我们就会进一去想知道XY...

[Day6] 初见输入系统

今日目标 键盘滑鼠输入 GLFW Input Callback 第一篇的时候,有简单的介绍glfw管...

[Day24]创建Table及捞取资料

创建migration迁移档案 首先先使用artisan指令: make:migration 创建一...

用html和css做出网页的标题栏

今天来说如何用html和css做出网页上方的标题栏,就像iT邦帮忙网页中蓝色的那栏 首先我们新增一个...

VSCode 套件推荐系列 - 下

最後一篇,持续来介绍 VSCode 的套件,让你靠一套文字编辑器在路上横着走! CodeSpellC...