let a = 1
let b = 2
[a, b] = [b, a]
console.log(a)
console.log(b)
让b = 2
(不使用分号)会导致错误:
2。
let a = 1
let b = 2
let c = 3
[a, b] = [b, a]
console.log(a)
console.log(b)
console.log(c)
让c = 3
没有分号,没有错误,c
将变成一个数组。为什么会这样?
答案 0 :(得分:5)
自动分号插入有一些奇怪之处,这就是其中之一。在您的第一个示例中,第二行的末尾不会插入任何分号,因此它将像这样读取解析器:
let b = 2[a, b] = [b, a];
这将引发异常,因为b尚不存在,但它正试图用于定义自身。示例2看起来很相似,但是现在引用的是已经存在的变量,因此除了一个异常外,您还拥有一段看起来非常奇怪的代码:
let c = 2[a, b] = [b, a];
关于这意味着什么,首先让我们看一下2[a, b]
。数字被装箱到对象上,因此可以访问它们的属性。因此,例如,您可以执行以下操作:
let temp = 2;
console.log(temp.toString());
temp是一个数字对象,并且上面具有toString属性。现在,由于.
字符对数字具有特殊含义(它是一个小数点),因此您不能将其与数字文字一起使用,因此以下内容是非法的:
2.toString();
但是可以使用方括号语法,例如:
2['toString']()
该括号语法就是我们在2[a, b]
中拥有的语法:它试图访问2上的一个属性。哪个属性? 2 [b],它分解为2 [2]。 a
与奇怪的comma operator一起使用,并且基本上被忽略了。
2 [2]是什么?没什么,只是undefined
的属性。而且,如果您尝试分配给它,则不会有什么值得注意的事情,因为数字不允许您像这样修改它们的属性。但是,您仍然可以根据需要尝试分配给它,它将以静默方式失败(无论如何在非严格模式下)。
因此,总结一下2[a, b] = [b, a];
的作用:它创建一个包含元素[b, a]
的数组,然后尝试将其分配给2 [2]。这对数字2没有任何作用,但是您尝试分配的值确实成为了表达式的结果,因此2[a, b] = [b, a];
的结果仅为[b, a]
,即[2, 1]
。由于代码let c = //etc
答案 1 :(得分:4)
神奇之处在于分号。没有行分隔符,编译器会感到困惑,并且不知道“预期”逻辑是什么。它将换行视为仅空白。因此,
let c = 3
[a, b] = [b, a]
转换为单行语句let c = 3[a, b] = [b, a]
。
现在由于双重分配,将使用后面的分配([b, a]
)。
c
现在成为包含b
和a
的数组。 / p>
这可以在下面看到:
let a = 1
let b = 2
let c = 3
[a, b] = [b, a]
console.log(c)
请注意,您只需添加分号即可收到“期望的”输出:
let a = 1;
let b = 2;
let c = 3;
[a, b] = [b, a];
console.log(c);
答案 2 :(得分:2)
黑曜石时代在他的回答中很好地说明了这一点,但没有说明案例1。所以,就在这里。
情况1:
let a = 1
let b = 2
[a, b] = [b, a]
console.log(a)
console.log(b)
在这里没有分号,编译器会这样理解。
let a = 1
let b = 2[a, b] = [b, a]
console.log(a)
console.log(b)
因此会给出引用错误,因为在您要声明b时尚未声明b。
答案 3 :(得分:2)
操作时:
let a = 1
let b = 2
[a, b] = [b, a]
您正在做
let a = 1
let b = 2[a,b] = (this is the assignment which you doing '[b,a]', but `b` is not defined yet)