03 April 2013

原文:ECMAScript 6 and Array Comprehension

我们已经看到了可变参数可以帮助处理可变数目的函数参数。其他方式怎么样呢?我们可以把一个数组转换成连续的函数参数吗?显然地,ECMAScript 6 定义了一个称为展开操作符的新操作符,用于处理这个操作。

让我们再次回顾前面的例子,其中有一辆供货卡车和一间杂货铺。假设杂货铺的 API 接受一个特定类目和可变数目的货物。

store.add('fruit', 'apple');
store.add('dairy', 'milk', 'cheese', 'yoghurt');
store.add('pastries', 'donuts', 'croissants');

我们假设这些美味的货物存储在一个箱子里,每个箱子恰好是一个数组:

var dairyBox = ['milk', 'cheese', 'yoghurt'];

用上面的数组调用杂货铺的 add 函数,一个可能的解决方案是使用 Function.prototype.apply。由于需要把食品类目作为第一个参数传入,Array.concat 是必需的。

store.add.apply(store, ['dairy'].concat(dairyBox));

对于未经过训练的眼睛,上面的代码看起来就像是神奇的 JavaScript 咒语。

在 ECMAScript 6 中,上面的代码可以通过使用展开表达式(11.2.5 节, ES6 草稿 Rev 14)的前缀 ... 简化。

store.add('dairy', ...dairyBox);

数组 dairyBox 被简单的展开,以填充其余参数列表

显然,在可能处理数组的地方,展开操作总是有用的。我们知道 push 可以接受多个参数。函数 add 最初的实现看起来就像这样:

store.add = function(category, ...items) {
  items.forEach(function (item) {
    store.aisle[category].push(item);
  });
};

可以进一步缩短为类似下面的代码片段。很俏,不是吗?

store.add = function(category, ...items) {
  store.aisle[category].push(...items);
};

(当然,如果你改变 API 以简单的接受一个货物数组,而不是使用了展开操作符的可变参数,上面的做法是不必要的。)

展开操作符的使用可以延伸出一种合并数组的不同方式:

var x = [1, 2];
var y = [3, 4];
x.push(...y);  // x is [1, 2, 3, 4]

一旦滥用展开操作符,你头脑中会有什么其他的技巧?



blog comments powered by Disqus