简体   繁体   English

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

[英]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: b = 2 (没有分号)会出错:

在此输入图像描述

2. 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. c = 3没有分号,没有错误, c将变成一个数组。 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. 这引发了一个异常,因为b尚不存在,但它正试图用来定义自己。 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: 示例2看起来类似,但现在指的是已经存在的变量,因此您只需要一个非常奇怪的代码片段而不是异常:

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

As for what this means, well, first let's look at 2[a, b] . 至于这意味着什么,首先让我们看看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. temp是一个数字对象,它上面有一个toString属性。 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[a, b] :它试图访问2.属性? 2[b], which resolves to 2[2]. 2 [b],解析为2 [2]。 The a is being used with the weird comma operator , and basically gets ignored. a与奇怪的逗号运算符一起使用 ,基本上被忽略了。

What's at 2[2]? 什么是2 [2]? Nothing really, just a property that's undefined . 没什么,只是一个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]; 总结一下2[a, b] = [b, a]; does: It creates an array with elements [b, a] , and then attempts to assign that to 2[2]. 确实:它创建一个包含元素[b, a]的数组,然后尝试将其分配给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]; 这对数字2没有任何作用,但是您尝试分配的值确实成为表达式的结果,因此2[a, b] = [b, a]; is just [b, a] , which is [2, 1] . 只是[b, a] ,这是[2, 1] This, in turn, gets assigned to c, due to the code let c = //etc 反过来,这被分配给c,因为代码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] . 变换为单行语句let c = 3[a, b] = [b, a]

Now because of the double assignment, the later assignment is used ( [b, a] ). 现在由于双重赋值,使用后面的赋值( [b, a] )。
c now becomes an array containing b then a . c现在变成一个包含b然后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. 黑曜石时代在他的回答中解释得很好但案例1没有解释。 So, here is it. 所以,就是这样。

Case 1: 情况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. 因此给出了参考错误,因为当你要宣布b时,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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 JavaScript 中的 Quiz App 中问 5 次问题? - How to ask Question 5 Times in Quiz App in JavaScript? 我是 Photoshop 脚本初学者。 想请教大家如何替换文字图层 - I am a Photoshop scripting beginner. I want to ask everyone how to replace the text layer 当机器人问一个问题时,如何让他等待答案并问另一个问题 - How to make when bot ask a question, he waiting for an answer and ask another question 大家好,我是 jQuery 的新手,有人问我这个问题,但我不知道该怎么做 - Hi everyone , I am new to jQuery and I was asked this question but I don't know how to do it 在javascript中询问是/否问题的代码 - Code to ask yes/no question in javascript 在SO中键入问题时,在“如何提问”框中输入。 如何获得滚动效果? 纯CSS还是JS? - “How to Ask” box when typing a question in SO. How do get that scrolling effect? Pure CSS or JS? 如果之前的答案正确,我该如何使我的Quizbot提出另一个问题? - How can I make my quizbot ask another question if the answer before was correct? 如何为每个客户端同步计时器 - How to synchronise a timer for everyone client 使用 GitLab 持续部署 NodeJS - Continuous Deployment of a NodeJS using GitLab Ask Question “提问”中的后退按钮事件捕获 - Back button event capturing in “Ask Question”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM