JavaScript中数组的迭代方法详解(二)

JavaScript中数组的迭代方法详解(二)

接着上一篇来分析:

5、filter

filter为“过滤”、“筛选”之意。指数组filter后,返回过滤后的新数组。用法跟map极为相似:

from MDN
filter() 方法使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组。

//语法
[].filter(function(value, index, array){
   // do some
})

callback参数
1. value(当前值)---数组中正在处理的当前元素
2. index(索引)  ---数组中正在处理的当前元素的索引
3. array        ---正在应用forEach()数组
[1, 5, 8, 3, 4].filter(function (value) {
  return value < 10;
})  ==>[1, 5, 8, 3, 4]


[1, 5, 8, 3, 4].filter(function (value) {
  return value > 10;
})  ==>[]

将原数组中每个元素执行一次callback函数,把每次执行后返回true的元素组合起来形成一个新数组,fliter()方法返回值就是这个新数组。如果素所有元素运行函数时都返回 false,则返回空数组[]。

可能会疑问,一定要是Boolean值吗?我们可以简单测试下嘛,如下:

var data = [0, 1, 2, 3];
var arrayFilter = data.filter(function(item) {
    return item;
});
console.log(arrayFilter); // [1, 2, 3]

有此可见,返回值只要是弱等于true/false就可以了,而非非得返回 === true/false。

特点:

  • filter方法不改变原数组
  • filter方法对数组中的所有元素逐个过滤,挑选出符合条件的元素生成新的数组
  • filter方法的返回值为Array类型

一张图说明:

6、reduce

from MDN
reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值。

[].reduce(callback,[initialValue])


callback 被调用时传入四个参数:
1. 上一次调用回调返回的值,或者是提供的初始值(initialValue)
2. 当前元素的值
3. 元素的索引
4. 调用reduce的数组

initialValue   ===>作为第一次调用 callback 的第一个参数。

回调函数第一次执行时,previousValue 和 currentValue 的取值有两种情况。

  • 如果 initialValue 在调用 reduce 时被提供,那么第一个 previousValue 等于 initialValue ,并且currentValue 等于数组中的第一个值;
  • 如果initialValue 未被提供,那么previousValue 等于数组中的第一个值,currentValue等于数组中的第二个值。
  • 如果数组为空并且没有提供initialValue, 会报错。
  • 如果数组仅有一个元素(无论位置如何)并且没有提供initialValue,或者有提供initialValue但是数组为空,那么此唯一值将被返回并且callback不会被执行

例一:

[0,1,2,3,4].reduce(function(previousValue, currentValue, index, array){
  return previousValue + currentValue;
});

执行结果:

例二:

var arr = [0,1,2,3,4];
var arr1 = ["a","b","c","d","e"];

var isarr0 = arr.reduce(function(previousValue, currentValue, index, array){
	console.log("previousValue:"+previousValue+"! currentValue:"+currentValue+"! index:"+index+"! array:"+array+"! this:"+this);
},arr1);

isarr0;



结果:

previousValue:a,b,c,d,e! currentValue:0! index:0! array:0,1,2,3,4! this:[object Window]
previousValue:undefined! currentValue:1! index:1! array:0,1,2,3,4! this:[object Window]
previousValue:undefined! currentValue:2! index:2! array:0,1,2,3,4! this:[object Window]
previousValue:undefined! currentValue:3! index:3! array:0,1,2,3,4! this:[object Window]
previousValue:undefined! currentValue:4! index:4! array:0,1,2,3,4! this:[object Window]

一张图说明:

7、reduceRight

from MDN
reduceRight() 方法接受一个函数作为累加器(accumulator),让每个值(从右到左,亦即从尾到头)缩减为一个值。(与 reduce() 的执行方向相反)

[].reduceRight(callback[, initialValue])


callback 被调用时传入四个参数:
1. 上一次调用回调返回的值,或者是提供的初始值(initialValue)
2. 当前元素的值
3. 元素的索引
4. 调用reduce的数组

initialValue   ===>作为第一次调用 callback 的第一个参数。
[0, 1, 2, 3, 4].reduceRight(function(previousValue, currentValue, index, array) {
    return previousValue + currentValue;
});

结果:

如果提供了一个 initialValue 参数,则结果如下:

[0, 1, 2, 3, 4].reduceRight(function(previousValue, currentValue, index, array) {
    return previousValue + currentValue;
}, 10);

reduce 与 reduceRight 之间的区别

var a = ["1", "2", "3", "4", "5"]; 
var left  = a.reduce(function(prev, cur)      { return prev + cur; }); 
var right = a.reduceRight(function(prev, cur) { return prev + cur; }); 

console.log(left);  // "12345"
console.log(right); // "54321"

8、every

from MDN
every() 方法测试数组的所有元素是否都通过了指定函数的测试。

every 要求每一项都合乎要求。

[].prototype.every(callback[, thisArg])

callback : 用来测试每个元素的函数
thisArg:执行callback时使用的this值



callback参数
1. value(当前值)---数组中正在处理的当前元素
2. index(索引)  ---数组中正在处理的当前元素的索引
3. array        ---原数组

对数组中的每一项执行callback,返回true或者false, 最终的返回值由每一项的结果所决定。

例一:

var scores = [5, 8, 3, 10];
var current = 7;

function higherThanCurrent(score) {
  return score > current;
}

scores.every(higherThanCurrent)


结果:
第一项==> false
第二项==> true 
第三项==> false
第四项==> true 

最终结果==> false

例二:

var scores = [15, 18, 13, 10];
var current = 7;

function higherThanCurrent(score) {
  return score > current;
}

scores.every(higherThanCurrent)


结果:
第一项==> true 
第二项==> true 
第三项==> true
第四项==> true 

最终结果==> true 
  • 返回Boolean值
  • every 不会改变原数组
  • 除了数组对象之外,every 方法可由具有 length 属性且具有已按数字编制索引的属性名的任何对象使用

一张图说明:

9、some

some 和 every 可以对应的来记,都是返回Boolean值。

some意指“某些”,指是否“某些项”合乎条件,只要有一项符合返回true,最终的结果就是true,反之为false。

from MDN
some() 方法测试数组中的某些元素是否通过了指定函数的测试。

[].some(callback[, thisArg])

callback : 用来测试每个元素的函数
thisArg:执行callback时使用的this值



callback参数
1. value(当前值)---数组中正在处理的当前元素
2. index(索引)  ---数组中正在处理的当前元素的索引
3. array        ---原数组
function isBigEnough(element, index, array) {
  return (element >= 10);
}
var passed = [2, 5, 8, 1, 4].some(isBigEnough);
// passed is false
passed = [12, 5, 8, 1, 4].some(isBigEnough);
// passed is true

一张图说明:

10、for…of

from MDN
for…of语句在可迭代对象(包括 Array, Map, Set, String, TypedArray,arguments 对象等等)上创建一个迭代循环,对每个不同属性的属性值,调用一个自定义的有执行语句的迭代挂钩

for (var value of myArray) {
    statement
}

特点

  • 比普通for简洁
  • 比forEach 灵活,支持break, continue, return
  • 比for..in 作用更大, 除了可以遍历数组,还可以以遍历遍历其它集合,如字符串、Map 和 Set 对象、DO 集合等

for…of与for…in的区别

  • for…in循环会遍历一个object所有的可枚举属性
  • for…of语法是为各种collection对象专门定制的,并不适用于所有的object.它会以这种方式迭代出任何拥有[Symbol.iterator] 属性的collection对象的每个元素

for…in 遍历每一个属性名称,而 for…of遍历每一个属性值:

下面的例子演示了for…of 循环和 for…in 循环的区别。

Object.prototype.objCustom = function () {}; 
Array.prototype.arrCustom = function () {};

let iterable = [3, 5, 7];
iterable.foo = "hello";

for (let i in iterable) {
  console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}

for (let i of iterable) {
  console.log(i); // logs 3, 5, 7
}