【问题标题】:What does curly brackets in the `var { ... } = ...` statements do?`var { ... } = ...` 语句中的大括号有什么作用?
【发布时间】:2013-02-23 19:40:11
【问题描述】:

不确定这是否是 Mozilla 特有的 JS 语法,但我经常发现变量以这种方式声明,例如在 add-on SDK docs

var { Hotkey } = require("sdk/hotkeys");

在各种 chrome Javascript 中(let 语句被用来代替var),

let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu }  = Components;

我发现它非常混乱,但我无法找到关于这两种语法的任何文档,即使在 MDN 上也是如此。

【问题讨论】:

标签: javascript ecmascript-6 destructuring javascript-1.7


【解决方案1】:

这是 JavaScript 中的破坏性赋值,是 ES2015 标准的一部分。它将数组中的值或对象的属性解压缩或提取到不同的变量中。

数组解构

无需解构

var foo = ["one", "two", "three"];
var one = foo[0];
var two = foo[1];
var three = foo[2];

console.log(one, two, three);

解构

var foo = ["one", "two", "three"];
var [one, two, three] = foo;

console.log(one, two, three);

对象解构

无需解构

var o = {p: 42, q: true};
var p = o.p;
var q = o.q;

console.log(p); //42
console.log(q); //true 

解构

var o = { p: 42, q: true };
var { p, q } = o;

console.log(p); //42
console.log(q); //true

分配新的变量名

var o = { p: 42, q: true };
var { p: foo, q: bar } = o;

console.log(foo); //42
console.log(bar); //true

【讨论】:

    【解决方案2】:

    您正在查看的是一个解构分配。它是 pattern matching 的一种形式,就像在 Haskell 中一样。

    使用解构赋值,您可以从对象和数组中提取值,并使用对象和数组字面量语法将它们分配给新声明的变量。这使得代码更加简洁。

    例如:

    var ascii = {
        a: 97,
        b: 98,
        c: 99
    };
    
    var {a, b, c} = ascii;
    

    上面的代码等价于:

    var ascii = {
        a: 97,
        b: 98,
        c: 99
    };
    
    var a = ascii.a;
    var b = ascii.b;
    var c = ascii.c;
    

    同样适用于数组:

    var ascii = [97, 98, 99];
    
    var [a, b, c] = ascii;
    

    这相当于:

    var ascii = [97, 98, 99];
    
    var a = ascii[0];
    var b = ascii[1];
    var c = ascii[2];
    

    您还可以按如下方式提取和重命名对象属性:

    var ascii = {
        a: 97,
        b: 98,
        c: 99
    };
    
    var {a: A, b: B, c: C} = ascii;
    

    这相当于:

    var ascii = {
        a: 97,
        b: 98,
        c: 99
    };
    
    var A = ascii.a;
    var B = ascii.b;
    var C = ascii.c;
    

    仅此而已。

    【讨论】:

    • +1 用于对象解构示例,它们真的很有帮助。 MDN examples 只显示数组解构。
    • @Blender - 他们确实提供了对象解构示例。看Looping across values in an array of objects
    • 我的意思是var {a, b, c} = ascii; 语法。
    • 最后一个例子真的很奇怪,因为通常冒号左边的就是分配的内容。
    【解决方案3】:

    它们都是 JavaScript 1.7 的特性。第一个是block-level variables

    let 允许您声明变量,将其范围限制为使用它的块、语句或表达式。这与 var 关键字不同,后者在全局范围内定义变量,或者在本地定义整个函数,而不管块范围如何。

    第二个叫destructuring

    解构赋值可以使用反映数组和对象字面量构造的语法从数组或对象中提取数据。
    ...
    使用解构赋值可以做的一件特别有用的事情是在单个语句中读取整个结构,尽管您可以用它们做很多有趣的事情,如以下充满示例的部分所示。

    对于熟悉 Python 的人来说,它类似于以下语法:

    >>> a, (b, c) = (1, (2, 3))
    >>> a, b, c
    (1, 2, 3)
    

    第一个代码块是以下的简写:

    var {Hotkey: Hotkey} = require("sdk/hotkeys");
    // Or
    var Hotkey = require("sdk/hotkeys").Hotkey;
    

    您可以将第二个代码块重写为:

    let Cc = Components.classes;
    let Ci = Components.interfaces;
    let Cr = Components.results;
    let Cu = Components.utils;
    

    【讨论】:

    • 另外,使用这种不常见的语法会使一切变得更加神秘。
    • 编写代码很容易,但编写人类可以阅读的代码却很难。我们是否需要构造来使其更难?
    • @Blender 输入更少的字符,使您的文件更小。对于可供公共下载的非常大的脚本,尽可能减小文件大小总是一个好主意。我知道这条评论比我回复的评论晚了 5 年半,但我觉得仍然值得把它放在这里让其他人看看他们是否偶然发现了这个答案和评论线程
    【解决方案4】:

    在 MDN 上有 let 语句的文档:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/let

    let 类似于var,因为它限制了声明变量的范围。它允许您在 if(){} 块(或其他块)内声明一个变量,并使该变量仅在该块内“可见”(到目前为止,JavaScript 具有函数作用域,而不像大多数其他语言那样具有块作用域)。所以let 基本上是对许多人有问题的“修复”。请注意,tihs 是 JavaScript 1.7 的一项功能。

    {Foo} 上没有找到任何东西。

    【讨论】:

      猜你喜欢
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 2021-10-21
      • 1970-01-01
      • 2013-04-23
      • 2016-12-04
      相关资源
      最近更新 更多