数组推导式

非标准。不要使用!
数组推导是非标准的。以后应该用 展开语法.。

 

数组推导式是一种 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 方法更简洁

对比数组的 filter 方法:

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草案中,但在第27版(2014年8月)中被移除。 请参阅ES 6的旧修订版的规范语义。

浏览器兼容性

Update compatibility data on GitHub
Desktop Mobile Server
Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Firefox for Android Opera for Android Safari on iOS Samsung Internet Node.js
Array comprehensions
Deprecated Non-standard
Chrome No support No Edge No support No Firefox No support 30 — 58 IE No support No Opera No support No Safari No support No WebView Android No support No Chrome Android No support No Firefox Android No support 30 — 58 Opera Android No support No Safari iOS No support No Samsung Internet Android No support No nodejs No support No

Legend

No support  
No support
Non-standard. Expect poor cross-browser support.
Non-standard. Expect poor cross-browser support.
Deprecated. Not for use in new websites.
Deprecated. Not for use in new websites.

同旧版的JS1.7/JS1.8数组推导的不同之处

 

JS1.7/JS1.8数组推导 在Gecko的46版本中已经被移除了 ( bug 1220564).

旧版数组推导语法 (请不要再使用了!):

[X for (Y in Z)]
[X for each (Y in Z)]
[X for (Y of Z)]

不同点:

  • ESNext数组推导为每个"for"创建了一个作用域而取代了整个作用域.
    • Old: [()=>x for (x of [0, 1, 2])][1]() // 2
    • New: [for (x of [0, 1, 2]) ()=>x][1]() // 1, each iteration creates a fresh binding for x.
  • ESNext 同"for"进行赋值而取代了旧的赋值表达式.
    • Old: [i * 2 for (i of numbers)]
    • New: [for (i of numbers) i * 2]
  • ESNext数组推导可由多个if和for组成
  • ESNext数组推导只和for...in 迭代.

点击查看 Bug 1220564, comment 42 并提出建设性建议.

相关链接