为什么JS用分号结尾和没用分号结尾执行的结果不一致?

代码1:
var a = 'Aaa';
var b = 'Bbb';
[a, b] = [b, a];
console.log(a);
console.log(b);

结果:
Bbb
Aaa


代码2:
var a = 'Aaa'
var b = 'Bbb'
[a, b] = [b, a]
console.log(a);
console.log(b);

结果:
Aaa
[ undefined, 'Aaa' ]

如果说JS并不强行要求每行语句末尾必须要用分号结尾的话,上面两段代码按道理来说结果不是应该一致的吗?

测试环境:node v6.10.2

阅读 4.6k
6 个回答

不强行要求分号不代表不写分号是正确的。解释器会自动加分号,不保证完全能按你的意思加分号也许就加错分号了,结果就错了。变成了

var a = 'Aaa';
var b = 'Bbb'[a, b] = [b, a];
console.log(a);
console.log(b);

其实代码和说话一样,加分号好比加上标点符号。你加了分号机器就按照你的意思来走,不加分号那机器就按照它的理解来走,

举个例子:

你说:下雨天留客天留我不留。

那别人理解为:
1、下雨天留客,天留我不留。
2、下雨天留客,天留,我不留。
3、下雨天留客,天留我?不留。
4、下雨天留客,天留我不?留。
5、下雨,天留客;天留我不留!
6、下雨天,留客天,留我?不留。
7、下雨天,留客天,留我不?留。
8、下雨天,留客天,留我不留?

代码也是一个意思,不同的结果只是因为有歧义,上面两个回答很好的说明了,我就不赘述了,?

并不是所有地方都可以不加分号。你的问题处在:

var b = 'Bbb'[a, b] = [b, a];

回头来看看这道题其实还蛮有意思的。所以我来继续讲解分析下:

================

详细讲解

为什么此时b输出:[undefined, "Aaa"]呢?

课外知识:首先这里有一个连等

var a = b =c;

这里b=c是一个赋值语句也是一个表达式,实际上是var a = (b = c),相当于:

b=c;
a=c;

回到原题:
原本使用[a,b]=[b,a]是用到了结构赋值的数组交换赋值。
but,一旦变成:var b = 'Bbb'[a, b] = [b, a]之后,意义就变了,变成了:

var b = [b, a]

这样就简单了,明显给b赋值一个数组,但是数组第一个元素b是undefined!
所以输出:
b = [undefined, "Aaa"]

不强制要求,是在没有歧义的情况下。你的第二句和第三句有歧义,合并为一条语句也可以。

再举个例子

a = func
(...)

不加分号会合并成一行,变成了执行func函数,会导致运行时错误或逻辑错误。

var aaa = 'Aaa'
var bbb = 'Bbb'
var [aaa, bbb] = [bbb, aaa]
console.log(aaa)
console.log(bbb)

不用分号也行

clipboard.png

看图就知道了,我 vscode 装的 Eslint ,可以自动格式化纠错的会自动格式化纠错,这样就看到解析器的执行逻辑了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题