数组推导式

该特性处于 ECMAScript 6 规范草案中,目前的实现在未来可能会发生微调,请谨慎使用。

概述

数组推导式是一种新的 JavaScript 表达式语法,使用它,你可以在一个原有数组的基础上快速的构造出(推导出)一个新的数组。

很多语言中都有推导式语法,现在 JavaScript 中也有了。

语法

[for (x of iterable) x]
[for (x of iterable) if (condition) x]
[for (x of iterable) for (y of iterable) x + y]

描述

在数组推导式内部,可以使用下面两种子语句:

每个 for-of 语句都放在与其配对的 if 语句(可以有多个,也可以完全省略)的左边,每个数组推导式中可以包含多组这样的配对,但最终选取的表达式值只能有一个,且这个值(也可以是个数组推导式,也就是说可以嵌套)只能放在推导式的最右边,紧靠着右中括号。

示例

基本的数组推导式写法

[for (i of [ 1, 2, 3 ]) i*i ]; 
// [ 1, 4, 9 ]

var abc = [ "A", "B", "C" ];
[for (letters of abc) letters.toLowerCase()];
// [ "a", "b", "c" ]

带有 if 语句的数组推导式

var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ];

[for (year of years) if (year > 2000) year];
// [ 2006, 2010, 2014 ]

[for (year of years) if (year > 2000) if(year < 2010) year];
// [ 2006], 和下面的写法等效:

[for (year of years) if (year > 2000 && year < 2010) year];
// [ 2006] 

用数组推导式比用数组的 mapfilter 方法更简洁

对比数组的 mapfilter 方法:

var numbers = [ 1, 2, 3 ];

numbers.map(function (i) { return i * i });
[for (i of numbers) i*i ];
// 返回值都是 [ 1, 4, 9 ]

numbers.filter(function (i) { return i < 3 });
[for (i of numbers) if (i < 3) i];
// 返回值都是 [ 1, 2 ]

带有两个数组的数组推导式

用两个 for-of 语句迭代两个不同的数组:

var numbers = [ 1, 2, 3 ];
var letters = [ "a", "b", "c" ];

var cross = [for (i of numbers) for (j of letters) i+j];
// [ "1a", "1b", "1c", "2a", "2b", "2c", "3a", "3b", "3c" ]

var grid = [for (i of numbers) [for (j of letters) i+j]];
// [
//  ["1a", "1b", "1c"],
//  ["2a", "2b", "2c"],
//  ["3a", "3b", "3c"]
// ]

[for (i of numbers) if (i > 1) for (j of letters) if(j > "a") i+j]
// ["2b", "2c", "3b", "3c"],和下面的写法等效:

[for (i of numbers) for (j of letters) if (i > 1) if(j > "a") i+j]
// ["2b", "2c", "3b", "3c"]

[for (i of numbers) if (i > 1) [for (j of letters) if(j > "a") i+j]]
// [["2b", "2c"], ["3b", "3c"]],和下面的写法不等效:

[for (i of numbers) [for (j of letters) if (i > 1) if(j > "a") i+j]]
// [[], ["2b", "2c"], ["3b", "3c"]]

规范

规范名称及链接 规范状态
ECMAScript 6 (ECMA-262)
Array comprehensions
Release Candidate

浏览器兼容性

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 未实现 30 (30) 未实现 未实现 未实现
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support 未实现 未实现 30.0 (30) 未实现 未实现 未实现

SpiderMonkey 目前实现的推导式特性存在的问题

SpiderMonkey 目前实现的 ES6 推导式和之前实现的 ES4 推导式(JS1.7/JS1.8)的区别

  • ES6 推导式中的 for-of 语句会为每次迭代分配一个新的作用域:
    • 旧写法:[()=>x for (x of [0, 1, 2])][1]() // 2
    • 新写法:[for (x of [0, 1, 2]) ()=>x][1]() // 1, 每个闭包都引用了一个不同的上层变量 x
  • ES6 推导式要求最终选取的表达式值放在最右边,而不是最左边,这样更符合英语的阅读习惯:
    • 旧写法:[i * 2 for (i of numbers)]
    • 新写法:[for (i of numbers) i * 2]
  • ES6 推导式中可以包含多个 for 语句和 if 语句,以前都只能写一个。
  • ES6 推导式中只能使用 for...of 语句,以前还可以使用 for...in

相关链接

文档标签和贡献者

 此页面的贡献者: SphinxKnight, ziyunfei
 最后编辑者: SphinxKnight,