在线文档教程

Array comprehensions

Array comprehensions

非标准。不要使用

数组理解是非标准的。对于面向未来的用途,可以考虑使用Array.prototype.mapArray.prototype.filter,箭头的功能,传播语法。

阵列理解语法是一个 JavaScript 表达式,它允许您快速组装基于现有的一个新的数组。理解存在于许多编程语言中。

根据 ECMAScript 4 的提议,请参阅下面的 SpiderMonkey 中的旧数组理解语法的差异。

语法

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

描述

在数组解析中,这两种组件是允许的:

  • for...of 以及

for-of迭代总是第一个组件。多次迭代或 if 语句被允许。

先前提出的数组理解在 ECMAScript 2016 中是标准化的,它提供了基于另一个内容构建新数组的有用捷径。内涵往往可以拨打电话到的使用map()filter(),或合并两者的一种方式。

以下理解需要一个数字数组,并为每个数字的浮点创建一个新数组的。

var numbers = [1, 2, 3, 4]; var doubled = [for (i of numbers) i * 2]; console.log(doubled // logs 2,4,6,8

这相当于以下map()操作:

var doubled = numbers.map(i => i * 2

Comprehensions 也可以用来选择符合特定表达式的项目。这是一个只选择偶数的理解:

var numbers = [1, 2, 3, 21, 22, 30]; var evens = [for (i of numbers) if (i % 2 === 0) i]; console.log(evens // logs 2,22,30

filter() 可以用于相同的目的:

var evens = numbers.filter(i => i % 2 === 0

map()filter()风格的操作可被组合成一个单一的阵列理解。这是一个只过滤偶数的函数,然后创建一个包含他们的双精度的数组:

var numbers = [1, 2, 3, 21, 22, 30]; var doubledEvens = [for (i of numbers) if (i % 2 === 0) i * 2]; console.log(doubledEvens // logs 4,44,60

数组理解的方括号为范围目的引入了一个隐含的块。新变量(如示例中的i)被视为已被声明为使用let。这意味着他们不能在理解之外获得。

数组理解的输入本身不需要是数组; 迭代器和生成器也可以使用。

即使字符串可以用作输入; 以实现上面的过滤器和贴图操作(在类似数组的对象下):

var str = 'abcdef'; var consonantsOnlyStr = [for (c of str) if (!(/[aeiouAEIOU]/).test(c)) c].join('' // 'bcdf' var interpolatedZeros = [for (c of str) c + '0' ].join('' // 'a0b0c0d0e0f0'

同样,输入表单不会被保留,所以我们必须使用join()返回到一个字符串。

示例

简单的数组理解

[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], the same as below: [for (year of years) if (year > 2000 && year < 2010) year]; // [2006]

数组理解与map和filter的对比

理解数组理解语法的一个简单方法是将其与数组mapfilter方法进行比较:

var numbers = [1, 2, 3]; numbers.map(function (i) { return i * i } numbers.map(i => i * i [for (i of numbers) i * i]; // all are [1, 4, 9] numbers.filter(function (i) { return i < 3 } numbers.filter(i => i < 3 [for (i of numbers) if (i < 3) i]; // all are [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"], the same as below: [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"]], not the same as below: [for (i of numbers) [for (j of letters) if (i > 1) if(j > 'a') i + j]] // [[], ["2b", "2c"], ["3b", "3c"]]

规范

最初是在 ECMAScript 2015 草案中,但在修订版 27(2014年8月)中被删除。有关规范语义,请参阅 ES2015 的旧版本。

浏览器兼容性

FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic supportNo support30 (30)No supportNo supportNo support

FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic supportNo supportNo support30.0 (30)No supportNo supportNo support