没有var的对象分解


97

如果对象解构var前面没有关键字,为什么会抛出错误?

{a, b} = {a: 1, b: 2};

抛出 SyntaxError: expected expression, got '='

以下三个示例可以正常工作

var {a, b} = {a: 1, b: 2};
var [c, d] = [1, 2];
    [e, f] = [1, 2];

额外的问题:为什么我们不需要var数组解构?

我在做类似的事情时遇到了问题

function () {
  var {a, b} = objectReturningFunction();

  // Now a and b are local variables in the function, right?
  // So why can't I assign values to them?

  {a, b} = objectReturningFunction();
}

Answers:


158

问题源于{...}运算符在JavaScript中具有多种含义。

{出现在Statement的开头时,它将始终代表一个,该不能分配给该。如果它稍后在Statement中作为Expression出现,则它将表示一个Object。

var有助于使这种区别,因为它不能跟一个声明,如将分组括号

( {a, b} = objectReturningFunction() );

来自他们的文档:https : //developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration

注意:当使用不带声明的对象文字解构赋值时,在赋值语句的括号(...)是必需的。

{a,b} = {a:1,b:2}是无效的独立语法,因为左侧的{a,b}被认为是一个块,而不是对象文字。

但是({{a,b} = {a:1,b:2})是有效的,var {a,b} = {a:1,b:2}也有效

您的(...)表达式必须以分号开头,或者可以将其用于执行上一行的功能。


如果它稍后在Statement中作为表达式出现,则它将表示一个Object。这是否意味着我们永远不能在分组括号内使用块作用域
sharad_kalya,

分组括号提示是一个很好的提示。
詹姆斯·史密斯

这是使我难堪的一门晦涩难懂的知识。它允许跨范围进行销毁(嗯,当然,您仍然需要声明变量)。但是,它解决了使用Promise链的约束,同时需要使用从Promise链的一个步骤解决的多个变量在另一个步骤中解决的问题,而不会造成太多混乱。谢谢。
凯文·泰勒

22

如果您编写的Javascript不带分号,则“无声明的赋值”语法应以分号开头,以使其可预期地工作

let a, b

;({a, b} = objectReturningFunction()) // <-- note the preceding ;

只是想突出显示这一点,因为它吸引了我,并希望可以节省一些时间弄清楚为什么它不起作用和/或使用诸如代码格式化程序产生奇怪的结果prettier

确实,它实际上就在公认的答案中(引用文档的最后一行),但很容易遗漏,尤其是在没有看到示例的情况下!


1
是的 人们使用分号的原因!
jfriend00

0

这是另一种方式:

let {} = {a, b} = objectReturningFunction()

优点:

  • 无需括号
  • 无需分号

缺点:

  • 看起来有点怪异,尽管我认为没有IIFE怪异!(){...}()
  • 可能会混淆为什么它在那里

类似于IIFE的感觉;({ a, b })比具有可比性let {} = { ... }。虽然不错。:)
shuckster

@ proto-n,+ 1,非常聪明的主意。您是怎么遇到的?
佩斯里耶
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.