在扩展语法 jn javascript 后有分号会中断执行并出现错误 "Unexpected token ="

Having semicolon after spread syntax jn javascript breaks execution with error "Unexpected token ="

谁能解释一下原因

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

这有效

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

这不是(注意末尾的分号)

根据 MDN documentation:

,您缺少括号

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);

我猜第一个是 Chrome 实现中的错误,因为 Firefox 会抛出错误。

Chrome

火狐

这与扩展语法或分号无关。

没有以 varconstlet 之类的内容开头的对象解构赋值必须使用括号(或以其他方式作为表达式出现在更大的包含它的语句),否则 JS 会将左大括号解析为块的开头:

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

同时,在这里使用扩展语法没有意义,所以你可以删除它:

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

这是 Chrome 的 of 的产物。即它会自动换行括号中的某些表达式(或评估它们 就好像 换行,没有区别)所以

{a} = {a: true}

实际上被评估为好像

({a} = {a: true})

第一个 不是 一个有效的语句,但是,因为 {} 被评估为 a code block - 与 [=17= 相同的构造] 或 for() {}function() {},而不是对象字面量语法或对象解构语法。

应注意,这是对代码的 正确 解释 - 它应该抛出语法错误,因为它无效:

{a} = {a: true}

可以添加括号以避免开始 { 被解释为代码块:

({a} = {a: true})

console.log(a);


Chrome 的控制台对您隐藏了它。为了进行比较,Firefox 也产生相同的结果 - 错误。

但是,当您添加分号时,表达式将不再对圆括号有效:({a} = {a: true};) 没有任何意义,因此 Chrome 完全按照书写的方式计算它,这也是 两种情况下的正确解释:

{a} = {a: true};

此行为存在于 V8 相关的 REPL 环境中。例如,在 Opera 或 Node.JS REPL 中也可以观察到同样的情况。当评估在正常上下文中而不是 REPL 中的代码时,使用常规解析规则并且表达式 {a} = {a: true} 会抛出错误。 See here on repl.it 或换个地方测试

  • 创建一个包含 {a} = {a: true} 的文件并通过节点执行它(repl.it 中的中间面板)
  • 在节点 REPL 中输入相同的代码(repl.it 中的右侧面板)

如果您想知道“为什么不忽略一般情况下的代码块”,这可能会导致错误或至少会导致语法混乱。例如,这是 valid code,它使用代码块:

let a = 1;

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

console.log("outside block", a);

{} 视为除代码块以外的任何东西都会有问题。