列出所有的数组遍历方法,方便查阅。
for ( ; ; ) { … }
这是最传统的方法
1 | const arr=[1,2,3]; |
for … in
语法如下:
1 | for(variable in object) |
variable 是声明一个变量的语句,在循环体内部,对象的一个属性名会被作为字符串赋给变量 variable。数组也是一种特殊的 Object。
该方法不仅可以遍历数组,还可以遍历对象。对象的有些属性标记成了只读的,永久的(不可删除的)或者不可枚举的,这些属性使用 for/in 循环不能枚举出来。虽然所有的用户定义的属性都可以枚举,但是许多内部属性,包括所有的内部方法都是不可枚举的。另外对象可以继承其他对象的属性,那些已继承的用户定义的属性可以使用 for/in 循环枚举出来。
1 | const arr=[1,2,3]; |
for ... in
方法只能遍历出对象可枚举的属性,判断对象的属性是否是可枚举的可以使用 Object.propertyIsEnumerable() 来判断。该方法返回一个布尔值,表明指定的属性名是否是当前对象可枚举的自身属性。
1 | const obj = {prop: 123}; |
要修改一个对象属性的可枚举等属性需要用到 Object.defineProperty(obj, prop, descriptor) 方法。
for … of
遍历 Array 可以采用下标循环,遍历 Map 和 Set 就无法使用下标。Map
,Set
结构无下标,无法使用索引进行遍历。为了统一集合类型,ES6 标准引入了新的 iterable 类型。
Array
、Map
和Set
都属于 iterable 类型。具有 iterable 类型的集合可以通过新的for … of
循环来遍历。
1 | const arr=[1,2,3]; |
for … of 循环和 for … in 循环有何区别
for … in
循环,它遍历的实际上是对象的属性名称。一个 Array 数组实际上也是一个对象,它的每个元素的索引被视为一个属性。当我们手动给 Array 对象添加了额外的属性后,for … in
循环将带来意想不到的意外效果:
1 | const arr=[1,2,]; |
而当我们使用 for ... of
时,它实际上是遍历的数组的值:
1 | const arr=[1,2,]; |
forEach
该方法是 ES5.1 标准引入的。方法返回值为 undefined
并且不可链式调用,没有办法中止或者跳出 forEach 循环,除了抛出一个异常。
该方法按升序为数组中含有效值的每一项执行一次 callback
函数,那些已删除(使用 delete 方法等情况)或者未初始化的项将被跳过(但不包括那些值为 undefined
的项)(例如在稀疏数组上)。
forEach
遍历的范围在第一次调用 callback
前就会确定。调用 forEach
后添加到数组中的项不会被 callback
访问到。如果已经存在的值被改变,则传递给 callback
的值是 forEach
遍历到他们那一刻的值。已删除的项不会被遍历到。如果已访问的元素在迭代时被删除了(例如使用 shift()
) ,之后的元素将被跳过。
使用方法如下:
1 | array.forEach(callback(currentValue, index, array){ |
如果给forEach
传递了thisArg
参数,当调用时,它将被传给 callback
函数,作为它的 this 值。否则,将会传入 undefined
作为它的 this 值。
1 | const arr=[1,2,3]; |
map
该方法返回一个新数组,数组中每个元素都是调用提供的函数后返回的结果,原数组不变。
使用方法为(参数含义与 forEach
相似):
1 | let array = arr.map(function callback(currentValue, index, array) { |
1 | var numbers = [1, 4, 9]; |
该方法后续可以跟上数组其他方法,例如:
1 | var str = '12345'; |
reduce
该方法对累加器和数组中的每个元素(从左到右)应用一个函数,将其减少为单个值,并返回这个值。原数组不变。
1 | arr.reduce(function (previous, current, index, arr) { ... }[, initialValue]) |
callback
函数接受 4 个参数:之前值、当前值、索引值以及数组本身。initialValue
参数可选,表示初始值。若指定,则当作最初使用的previous
值;如果缺省,则使用数组的第一个元素作为previous
初始值,同时current
往后排一位,相比有initialValue
值少一次迭代。
1 | let sum = [1, 2, 3, 4].reduce((previous, current, index, array) => previous + current); |
filter
返回经过过滤后的数组。原数组不变,用法与forEach
相似。
1 | array.filter(callback,[ thisObject]); |
filter
的callback
函数需要返回布尔值true
或false
。如果为true
,则表示通过筛选;若为false
,则会被过滤掉。返回值只需要弱等于== true/false
就可以了,并非=== true/false
。
1 | var data = [0, 1, 2, 3]; |
some
该方法测试数组中的某些元素是否通过由提供的函数给出的条件。若某一项符合则返回true
,否则返回false
。原数组不变。
1 | arr.some(callback[, thisArg]) |
callback
函数需要返回值,只需要弱等于== true/false
就可以了。我们自然可以使用forEach
进行判断,不过,相比some
, 不足在于,some
只有有true
即返回不再执行了。
1 | var scores = [5, 8, 3, 10]; |
every
用法与some
完全相似,区别在于every
需要所有的元素都满足条件才会返回true
,某一项不符合就会返回false
。