简体   繁体   中英

Ask everyone a question, how is this analyzed?

 let a = 1 let b = 2 [a, b] = [b, a] console.log(a) console.log(b) 

Let b = 2 (without a semicolon) will give an error:

在此输入图像描述

2.

 let a = 1 let b = 2 let c = 3 [a, b] = [b, a] console.log(a) console.log(b) console.log(c) 

Let c = 3 without a semicolon, no error, c will turn into an array. Why is this?

在此输入图像描述

Automatic semicolon insertion has some quirks, and this is one of them. In your first example, no semicolon will be inserted at the end of line two, and thus it reads to the parser like this:

let b = 2[a, b] = [b, a];

This throws an exception because b doesn't exist yet and yet it's trying to be used to define itself. Example 2 looks similar, but now is referring to variables that already exist, so rather than an exception you just have a really bizarre looking piece of code:

let c = 2[a, b] = [b, a];

As for what this means, well, first let's look at 2[a, b] . Numbers get boxed to objects, so it is possible to access properties on them. That's why for example, you can do the following:

let temp = 2;
console.log(temp.toString());

temp is a number object, and it has a toString property on it. Now, because the . character has a special meaning for numbers (it's a decimal point), you can't use it with a number literal, so something like the following is illegal:

2.toString();

But it's fine to use the bracket syntax, as in:

2['toString']()

That bracket syntax is what we have in 2[a, b] : It's trying to access a property on 2. Which property? 2[b], which resolves to 2[2]. The a is being used with the weird comma operator , and basically gets ignored.

What's at 2[2]? Nothing really, just a property that's undefined . And if you try to assign to it, nothing of note is going to happen, because numbers don't let you modify properties on them like that. But you can still try to assign to it if you want, and it will just silently fail (in non-strict mode anyway).

So to summarize what 2[a, b] = [b, a]; does: It creates an array with elements [b, a] , and then attempts to assign that to 2[2]. This doesn't do anything to the number 2, but the value you tried to assign does become the result of the expression, so the result of 2[a, b] = [b, a]; is just [b, a] , which is [2, 1] . This, in turn, gets assigned to c, due to the code let c = //etc

The magic is in the semicolon . Without a line separator, the compiler gets confused and doesn't know what the 'intended' logic is. It treats the new line as mere whitespace . Thus,

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

gets transformed to the single-line statement let c = 3[a, b] = [b, a] .

Now because of the double assignment, the later assignment is used ( [b, a] ).
c now becomes an array containing b then a .

This can be seen in the following:

 let a = 1 let b = 2 let c = 3 [a, b] = [b, a] console.log(c) 

And note that you receive the 'desired' output with the simple addition of the semicolon:

 let a = 1; let b = 2; let c = 3; [a, b] = [b, a]; console.log(c); 

Obsidian Age explains it well in his answer but case 1 is not explained. So, here is it.

Case 1:

let a = 1
let b = 2
[a, b] = [b, a]
console.log(a)
console.log(b)

Here without semicolon, the compiler will understand it like this.

 let a = 1 let b = 2[a, b] = [b, a] console.log(a) console.log(b) 

hence gives reference error because b has not been declared in when you are about to declare b.

When you do:

let a = 1
let b = 2
[a, b] = [b, a]

You're doing:

let a = 1
let b = 2[a,b] = (this is the assignment which you doing '[b,a]', but `b` is not defined yet)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM