问大家一个问题,这是如何分析的?

时间:2019-02-21 03:31:34

标签: javascript

let a = 1

let b = 2

[a, b] = [b, a]

console.log(a)

console.log(b)

b = 2(不使用分号)会导致错误:

enter image description here

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将变成一个数组。为什么会这样?

enter image description here

4 个答案:

答案 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

,这又分配给了c

答案 1 :(得分:4)

神奇之处在于分号。没有行分隔符,编译器会感到困惑,并且不知道“预期”逻辑是什么。它将换行视为仅空白。因此,

let c = 3
[a, b] = [b, a]

转换为单行语句let c = 3[a, b] = [b, a]

现在由于双重分配,将使用后面的分配([b, a])。
c现在成为包含ba的数组。 / 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)