简体   繁体   English

在扩展语法 jn javascript 后有分号会中断执行并出现错误“意外标记 =”

[英]Having semicolon after spread syntax jn javascript breaks execution with error “Unexpected token =”

Can someone explain me why有人可以解释我为什么

 const getabc = ()=> ({a:'aa',b:'bb',c:123}); let a, b, c; { a, b, c } = {...getabc()}

this works这有效

and

 const getabc = ()=> ({a:'aa',b:'bb',c:123}); let a, b, c; { a, b, c } = {...getabc()};

this does not (note semicolon at the end)这不是(注意末尾的分号)

This has nothing to do with spread syntax or semicolons.这与展开语法或分号无关。

Object destructuring assignments that are not preceded with something like var , const , or let must use parentheses (or in some other way occur as a an expression within a larger statement containing it) because otherwise JS will parse the opening brace as the beginning of a block:前面没有varconstlet类的对象解构赋值必须使用括号(或以其他方式作为包含它的更大语句中的表达式出现),否则 JS 会将左大括号解析为 a 的开头堵塞:

 const getabc = ()=>({a:'aa',b:'bb',c:123}); let a, b, c; ({ a, b, c } = {...getabc()});

At the same time, there is no point in using spread syntax here, so you can remove that:同时,在这里使用扩展语法没有意义,因此您可以删除它:

const getabc = ()=>({a:'aa',b:'bb',c:123});
let a, b, c;
({ a, b, c } = getabc());

You are missing the parentheshis, as per MDN documentation :根据MDN 文档,您缺少括号:

A variable can be assigned its value with destructuring separate from its declaration.可以通过与其声明分开的解构来为变量赋值。

 var a, b; ({a, b} = {a: 1, b: 2}); 

 const getabc = ()=>({a:'aa',b:'bb',c:123}); let a, b, c; ({ a, b, c } = {...getabc()}); console.log(a,b,c);

My guess is that the first one is an error in Chrome implementation, since Firefox throws an error.我的猜测是第一个是 Chrome 实现中的错误,因为 Firefox 会引发错误。

Chrome铬合金

在此处输入图片说明

Firefox火狐

在此处输入图片说明

This is an artefact of Chrome's hidden way of helping developers .这是 Chrome 帮助开发人员隐藏方式的人工制品。 Namely it will auto-wrap certain expressions in parentheses (or evaluate them as if wrapped, there is no difference) so也就是说,它会在括号中自动包装某些表达式(或者包装一样评估它们,没有区别)所以

{a} = {a: true}

is actually evaluated as if实际上被评估为 if

({a} = {a: true})

The first one is not a valid statement, however, since the {} is evaluated as a code block - the same construct as if (cond) {} or for() {} or function() {} , instead of an object literal syntax or an object destructuring syntax.然而,第一个不是有效的语句,因为{}被评估为代码块- 与if (cond) {}for() {}function() {}相同的构造,而不是对象文字语法或对象解构语法。

Should be noted that this is the correct interpretation of the code - it should throw a syntax error because it's not valid:应该注意的是,这是对代码的正确解释——它应该抛出一个语法错误,因为它是无效的:

 {a} = {a: true}

adding parentheses can be done in to avoid the starting { being interpreted as a code block:可以添加括号以避免起始{被解释为代码块:

 ({a} = {a: true}) console.log(a);


Chrome's console hides that away from you. Chrome 的控制台会将其隐藏起来。 For comparison, Firefox also produces the same result - an error.为了比较,Firefox 也会产生相同的结果 - 一个错误。

However, when you add a semicolon, then the expression stops being valid for parentheses: ({a} = {a: true};) makes no sense, so Chrome evaluates it exactly as written which is also the correct interpretation in both cases:但是,当您添加分号时,表达式对括号不再有效: ({a} = {a: true};)没有意义,因此 Chrome 会完全按照所写的方式对其进行评估,这在两种情况下也是正确的解释:

 {a} = {a: true};

This behaviour is only present in V8 related REPL environments.此行为仅存在于与 V8 相关的 REPL 环境中。 The same can be observed in Opera or a Node.JS REPL, for example.例如,可以在 Opera 或 Node.JS REPL 中观察到相同的情况。 When evaluating code which is in a normal context and not the REPLs regular parsing rules are used and the expression {a} = {a: true} throws an error.当评估处于正常上下文而不是 REPL 的正则解析规则中的代码时,表达式{a} = {a: true}会引发错误。 See here on repl.it or test at another place在 repl.it 上查看这里或在其他地方测试

  • create a file that contains {a} = {a: true} and execute it via node (middle panel in repl.it)创建一个包含{a} = {a: true}并通过节点执行它(repl.it 中的中间面板)
  • entering the same code in a node REPL (right panel in repl.it)在节点 REPL 中输入相同的代码(repl.it 中的右侧面板)

In case you wonder "why not just ignore the code blocks in the general case", that will potentially lead to errors or at the very least confusing grammar.如果您想知道“为什么不在一般情况下忽略代码块”,这可能会导致错误或至少会导致语法混乱。 For example, this is valid code which uses code blocks:例如,这是使用代码块的有效代码

 let a = 1; { let a = 2; console.log("inside block", a); } console.log("outside block", a);

Treating the { and } as anything other than a code block would be a problem.{}视为代码块以外的任何东西都会有问题。

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

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