03 April 2013

原文:ECMAScript 6 and and Destructuring Assignment

在编程语言中,解构赋值表示使用模式提取对象的部分。如果我们参考 Common LISP,解构赋值绑定一组变量到一组对应的值,通常是绑定一个值到一个唯一变量。对于下一代 ECMAScript 6,解构功能 被定位为赋值表达的重要补充。

Python 开发人员可能已经熟悉序列拆封的概念。CoffeeScript 也有解构语法。火狐的 JavaScript 引擎 SpiderMonkey 已经支持解构赋值有一段时间了。最新的 ECMAScript 6 在 11.13.1 节定义了解构赋值。有两种不同的形式:数组模式和对象模式。

数组模式

变量的初始化可以一气呵成。下面的两行代码具有相同的效果,其中第一行使用了数组模式。

var [m, d, y] = [3, 14, 1977];
var m = 3, d = 14, y = 1977;

交换两个变量相当琐碎,不过这一次正如预期的那样工作。在内部,就像有一个临时变量以及一般的值交换一样,来处理数组。

x = 3; y = 4; [x, y] = [y, x]
temp = [y, x]; x = temp[0]; y = temp[1];

另一种使用数组重组的典型场景是有个返回值的函数。我们不再需要把返回值包装到一个对象中。另外,也不需要接受数组中的所有元素。

function now() { return [2, 6, 2013, 8, 0]; }
var [m, d] = now(); // m = 2, d = 6
var [,,year] = now(); // year = 2013

利用 Esprima 的可视化语法功能,说明数组模式的语法树相当容易。下图显示了一个例子。相比普通赋值或变量声明明显不同是,使用了一个数组模式,而不是一个普通的标识符。

对象模式

对象模式与数据模式非常相似,除了工作原理是匹配对象,而不是匹配数组索引。因此,我们很容易的挑选哪些我们感兴趣的而忽略其余的。与前面的例子类似,下面是处理一个函数的返回值的例子:

function today() { return { d: 6, m: 2, y: 2013 }; }
var { m: month, y: year } = today(); // month = 2, year = 2013

当前,在访问每个属性之前,没有什么可以阻止你指定一个持有(特定属性和值的)对象,而不是一个(持有所有属性和值的)对象模式。无论如何,由于没有这种额外的对象,代码看起来更干净(或者更甜,因为解构应该是一个语法糖),特别当它是循环的一部分时。

books.forEach(function ({ title: title, author: author }) { console.log(title, author) }; )

在上面的结构中,数组 books 中的每个元素可能含有关于特定 book 的冗长的信息。而我们只需要部分属性,可以通过对象模式直接提取这些信息。

一旦结合使用数组推导式,情况会变得更加有趣。例如下面的这行代码与上面的代码片段完全等价:

[console.log(t,a) for ({title: t, author: a} of books)];

你计划如何使用数组模式和对象模式呢?



blog comments powered by Disqus