你所不知道的 JavaScript 分号
前言
程序猿的世界中存在着各种 争论
,有缩进长度之争、缩进使用空格或tab之争等。在 JavaScript 中还存在着 分号
使用和不使用之争。
这是一段不使用分号的代码,看起来有点点优雅:
var play = (lyric) => console.log(lyric)
['来啊', '造作啊', '反正有大把时光'].forEach(play)
JavaScript 会根据上下文分析,使用 自动分号插入
来将分号有效插入到程序中。但是,所谓的 自动分号插入
怎么判断改在哪里插入?
基础
我们知道加分号是正确的,那我们将对下面的代码慢慢去除分号,来看看哪里可以省略哪里不可以省略。
代码:
(function () {
var player, echo, lyric;
lyric = ['来啊', '造作啊', '反正有大把时光'];
echo = function (lyric) {
console.log(lyric);
return true;
}
player = () => lyric.forEach(echo);
console.group('测试播放音乐');
player();
console.groupEnd();
console.group('测试返回值');
console.log(echo('test'));
console.groupEnd();
})();
输出:
base-00.png测试一:去除分号
代码:
(function () {
var player, echo, lyric
lyric = ['来啊', '造作啊', '反正有大把时光']
echo = function (lyric) {
console.log(lyric)
return true
}
player = () => lyric.forEach(echo)
console.group('测试播放音乐')
player()
console.groupEnd()
console.group('测试返回值')
console.log(echo('test'))
console.groupEnd()
})();
输出:
base-01.png总结:
根据这个结果,我们可以得到一个结论 自动分号插入
, 会在语句的结尾处插入 ;
, 但是不会在 }
后插入 ;
。
测试二:增加换行符
在strlimit
代码:
(function () {
var player,
echo,
lyric
lyric = [
'来啊',
'造作啊',
'反正有大把时光'
]
echo = function (lyric) {
console.log(lyric)
return
true
}
player = () => lyric.forEach(echo)
console.group('测试播放音乐')
player()
console.groupEnd()
console.group('测试返回值')
console.log(echo('test'))
console.groupEnd()
})();
输出:
base-02.png这个时候,可以观察到 测试返回值 中 true
变为了 undefined
,而其他的数据并没有出错。这是为什么了呢?
解答:
// 自动分号插入前
echo = function (lyric) {
console.log(lyric)
return
true
}
// 自动分号插入后
echo = function (lyric) {
console.log(lyric)
return ;
true;
}
显然,return ;
返回了一个 undefined
值而不是 true
。会产生这种插入问题的,除了 return
外还有:
-
throw
语句。 - 带有跳转标签 的
break
和continue
。
总结
-
自动分号插入
会对一行或者多行语句的结尾插入 分号。 - 不会在
}
后插入分号,但是会在}
前插入分号。 - 对于一些特殊的关键字不允许其换行
return
语句,throw
语句, 带有跳转标签 的break
或continue
。
拼接
测试 1
代码:
var b
b = [1,2,3,4,5]
b[1, 2, 3, 4] = 6
console.log(b)
输出:
对于 b[1, 2, 3, 4] = 6
相当于 b[4] = 6
,[]
中间相当于一个逗号表达式,所以数组中的结果如下。
测试 2
代码变形:
我们给上面的代码加点料,并加上分号,看看会发生什么事情:
(function() {
var a, b;
b = [1, 2, 3, 4, 5];
console.group('测试 forEach');
a = b;
[1, 2, 3, 4].forEach((value) => console.log(value));
console.groupEnd();
console.group('测试 a 的值');
console.log(a);
console.groupEnd();
})();
输出:
concat-02.png测试 3
代码:
我们再把上面代码中的分号去除掉进行观察:
(function() {
var a, b
b = [1, 2, 3, 4, 5]
console.group('测试 forEach')
a = b
[1, 2, 3, 4].forEach((value) => console.log(value))
console.groupEnd()
console.group('测试 a 的值')
console.log(a)
console.groupEnd()
})()
输出:
concat-03.png输出结果显示 TypeError
,这是因为 自动分号插入
相当于把 a = b
识别成了 a = b[1, 2, 3, 4].forEach(..)
。然后 b[1, 2, 3, 4]
返回值是 5
并不能使用 forEach
函数。
结论:
JavaScript 自动分号插入
会在换行后,解析语法错误时插入。当他在读取 a = b [1, 2, 3, 4]
时,语法并没有出现错误,所以将继续读取下去,并在 a = b[1, 2, 3, 4].forEach((value) => console.log(...));
插入分号。
其他测试例子
类似于 [
的 还有 (, +, -, /
符号。
例子1:
// 预期值
b = () => console.log('我是b');
a = b();
(()=>console.log('我是酱油'));
// 插入前
b = () => console.log('我是b')
a = b()
(()=>console.log('我是酱油'))
// 插入后
b = () => console.log('我是b')
a = b()(()=>console.log('我是酱油'));
例子2:
// 预期值
var a = 1, b = 2;
b = a;
+b;
console.log(b);
// 插入前
var a = 1, b = 2
b = a
+b
console.log(b)
// 插入后
var a = 1, b = 2;
b = a+b;
console.log(b);
例子3:
// 预期值
var a = 1, hello = 2;
b = a;
/hello/i.test("hello");
// 插入前
var a = 1, hello = 2
b = a
/hello/i.test("hello")
// 插入后
var a = 1, hello = 2;
b = a / hello / i.test("hello");
例子4:
// 预期值
(() => console.log(1))();
(() => console.log(2))();
// 插入前
(() => console.log(1))()
(() => console.log(2))()
// 插入后
(() => console.log(1))()(() => console.log(2))()
总结
-
自动分号插入
会逐行 读取 和 拼接语句,当下一条语句出现拼接错误后,才会在当前语句尾部增加;
。 -
注意
下一行开头的字符有 5 个需要留意的,分别是[
,(
,+
,-
,/
。
其他
我们除了在语句结尾使用分号外,在循环语句中也会使用到。
例子 1
// 喵的,显然不能省略啊!!!
for(i = 0; i < 10; i++) {
console.log(i);
}
例子 2
// 喵的,你运行给我看看!!!
(function () {
while(true)
})
// 汪的,要这样写啊!!!!!
(function () {
while(true);
})
总结
- 我们在讨论是否是使用
分号
的时候,也应该了解,使用与否所可能带来的问题。 - 自动分号插入会对一行或者多行语句的结尾插入分号。
- 不会在
}
后插入分号,但是会在}
前插入分号。 - 对于一些特殊的关键字
return
,throw
, 带标签的break
或continue
不允许其换行。 - 自动分号插入 会逐行 读取 和 拼接语句,当下一条语句出现拼接错误后,才会在当前语句尾部增加
;
。 - 注意下一行开头的字符有 5 个需要留意的,分别是
[
,(
,+
,-
,/
。 - 为了安全,可以考虑在文件开头或立即函数开头 补一个
;
。 - 分号不是你想省,想省就能省!!!
- 多读书,多看报,少吃零食,多睡觉。
参考
- 《Effective JavaScript》
打赏&联系
如果您感觉有收获,欢迎给我打赏,以激励我输出更多的优质内容。
打赏&联系本文原稿来自 PushMeTop