‘ var { ... } = ...’语句中的花括号有什么作用?

不确定这是否是 Mozilla 特有的 JS 语法,但我经常发现变量是这样声明的,例如,在 附加的 SDK 文档中:

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

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

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

我发现它非常令人困惑,但是我找不到任何关于这两种语法的文档,甚至在 MDN上也找不到。

29834 次浏览

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

let类似于 var,因为它限制了声明的变量的作用域。它允许您在 if(){}块(或其他块)中声明一个变量,并且该变量只在该块中“可见”(到目前为止,JavaScript 具有函数作用域,而不像大多数其他语言那样具有块作用域)。因此,let基本上是一个“修复”的东西,许多人有问题。请注意,tihs 是 JavaScript 1.7的一个特性。

{Foo}上没有发现任何东西。

它们都是 JavaScript 1.7的特性,第一个是 块级变量 :

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

第二个是 解构:

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

对于那些熟悉 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;

你现在看到的是一个解构任务,就像在哈斯克尔一样,是 ABc0的一种形式。

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

例如:

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;

就是这样。

这是 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