js-数组遍历方法的总结与辨析(强烈推荐every与some)

js-数组遍历方法的总结与辨析(强烈推荐every与some)

javascript中除了forEach等基础的遍历方法外,还有很多在遍历的同时做判断或修改数组的原生方法。这里记录一下常见方法的总结和相近方法的辨析。

一、一般的遍历所有元素

1.for
for (语句 1; 语句 2; 语句 3)
{
被执行的代码块
}

语句 1 (代码块)开始前执行
语句 2 定义运行循环(代码块)的条件
语句 3 在循环(代码块)已被执行之后执行
var arr=[1,2,3,4];
for (var i=0; i<arr.length; i++){
	document.write(arr[i] + "
"
); } for (var i=0; i<=3; i++){ document.write(arr[i] + "
"
); } //这两段的结果都是输出1至4
注意,语句 2会在代码块开始前判断,而语句 3 是在代码块执行后

2.for in
用for in不仅可以对数组,也可以对enumerable对象操作。是的,数组就是特殊的对象,索引就是从0开始有顺序的key。

var arr=[1,2,3,4];
for(let index in arr) {
   console.log(arr[index]);
};

对对象操作时参数为属性名【包含对象自身的和继承自原型链的可枚举(enumerable)属性,不含 Symbol 属性】。

 var A = {a:1,b:"hello world"};
 for(let k in A) {
    console.log(k,A[k]);
 }

3.forEach
array.forEach(function(value, index, arr),thisValue):用于调用数组每个元素,并将元素传递给回调函数(注意没有办法跳出或终止forEach语句,除非抛出异常)。

注意:forEach 遍历的index第一次调用 callback 前就会确定。一次循环中添加到数组中的项在下一次循环才会被访问到。如果已经存在的值被改变,则传递给 callback 的值是 forEach 遍历到它们那一刻的值。已删除的项不会被遍历到。

返回值:undefined。注意里面即便有return语句,依然返回undefined。
array.forEach((v,index) => {
  console.log(v);
});
array.forEach(function(v,index) {
    console.log(v);
});

4.for of
在ES6中,增加了一个for of循环,也可以用于字符串。

 let s = "helloabc";
    for(let c of s) {
        console.log(c);
    }

二、拼接所有元素为字符串

arrayObject.join(separator):
用于把数组中的所有元素放入一个字符串。

参数:
arrayObject -其内元素为一般对象时无法完整展示,数组、数字、字符串可以;
separator(可省略)-指定分隔符进行分隔;如果省略该参数,则使用逗号作为分隔符。
返回值:一个字符串。

实际上,对于元素全为字符串的数组,array.toString和array.join()有类似效果。

var a={b:2,c:"3"};
	var e=["Apple"]
	var d=["Banana","Orange",e];
	var fruits = [a, d, 123,"Mango"];
	var x=document.getElementById("demo");
	var y=document.getElementById("demo2");
	console.log(fruits.join());
	console.log(JSON.stringify(fruits));
	console.log(fruits.toString());

运行结果

三、拼接两个数组

1.任一遍历方法 + push
2.使用apply劫持数组的push方法(不常用,方法略)
3.使用es6中的 ‘…’ 扩展运算符。

var arr = [1, 2, 3];
var arr2 = [4, 5];
arr.push(...arr2);
console.log(arr)

4.(非循环)concat
注意concat()方法生成了一个新的数组,并不改变原来的数组。

四、在循环中寻找特定值

1.includes(ES6)
arr.includes(searchElement, fromIndex)斜体样式:用来判断一个数组是否包含一个指定的值,如果是返回 true。

参数:
searchElement	必须。需要查找的元素值。
fromIndex	可选。从该索引处开始查找 searchElement。如果为负值,则按升序从 array.length + fromIndex 的索引开始搜索。默认为 0。

如果fromIndex 大于等于数组长度 ,则返回 false 。该数组不会被搜索;如果 fromIndex 为负值,计算出的索引将作为开始搜索searchElement的位置。如果计算出的索引小于 0,则整个数组都会被搜索。
注意: IE 13 及更早版本不支持 includes() 方法。

2.find(ES6)
array.find(function(currentItem, index, arr),thisValue) :返回通过测试的数组的第一个元素的值,
在第一次调用 callback 函数时会确定元素的索引范围,因此在 find 方法开始执行之后添加到数组的新元素将不会被 callback 函数访问到。如果数组中一个尚未被callback函数访问到的元素的值被callback函数所改变,那么当callback函数访问到它时,它的值是将是根据它在数组中的索引所访问到的当前值。被删除的元素仍旧会被访问到。

参数:value:必须,代表当前元素,其他四个参数都是可选,index代表当前索引值,arr代表当前的数组,thisValue代表传递给函数的值,一般用this值,如果这个参数为空,undefined会传递给this值
返回值:返回符合测试条件的第一个数组元素的值,如果没有符合条件的则返回undefined。
注意: IE 11 及更早版本不支持 find() 方法。

3.findIndex(ES6)
array.findIndex(function(currentItem, index, arr),thisValue) :返回通过测试的数组的第一个元素的位置。
当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置,之后的值不会再调用执行函数。
如果没有符合条件的元素返回 -1。

注意: findIndex() 对于空数组,函数是不会执行的。
注意: findIndex() 并没有改变数组的原始值。
注意: IE 11 及更早版本不支持 findIndex() 方法。

五、基于旧数组生成新数组

1.filter
array.filter(function(currentItem, index, arr),thisValue): 创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
filter 遍历的元素范围在第一次调用 callback 之前就已经确定了。在调用 filter 之后被添加到数组中的元素不会被 filter 遍历到。如果已经存在的元素被改变了,则他们传入 callback 的值是 filter 遍历到它们那一刻的值。被删除或从来未被赋值的元素不会被遍历到。

参数:
function(必选)-根据return的布尔值判断是否符合条件
thisValue(可选)-对象作为该执行回调时使用,传递给函数,用作 "this" 的值。如果省略了 thisValue ,"this" 的值为 "undefined"。

返回值:返回数组,包含了符合条件的所有元素,如果没有符合条件的则返回空数组。
注意: filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。

实例: 输出数组 ages 中所有元素都大于 18 的元素:

var ages = [32, 33, 16, 40];
function checkAdult(age) {
   return age >= 18;
}

function myFunction() {
   console.log( ages.filter(checkAdult) );
}

2.map
array.map(callback(value, index, arr),thisValue):返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值
map方法会给原数组中的每个元素都按顺序调用一次callback函数,callback每次执行后的返回值(包括undefined)组合起来形成一个新数组。callback函数只会在有值的索引上被调用,那些从来没被赋过值或者使用delete删除的索引则不会被调用。使用map方法处理数组时,数组元素的范围是在callback方法第一次调用之前就已经确定了。在map方法执行的过程中,原数组中新增加的元素将不会被callback访问到,若已经存在的元素被改变或删除了,则他们传递到callback的值是map方法遍历到他们的那一刻的值,而被删除的元素将不会被访问到。

返回值:返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
注意:map不会改变原始数组;map()方法按照原始数组元素顺序依次处理元素

3.forEach与map异同
array.forEach(function(currentValue, index, arr), thisValue)【thisValue为可选,用作 “this” 的值;如果这个参数为空, “undefined” 会传递给 “this” 值】: 针对每一个元素执行提供的函数。

array.map(function(currentValue,index,arr), thisValue) 【thisValue为可选,对象作为该执行回调时使用,传递给函数,用作 “this” 的值】: 创建一个新的数组,其中每一个元素由调用数组中的每一个元素执行提供的函数得来。

相同:两者都不会对空数组进行检测(但原始对象不是数组会报错);
不同:返回值、是否修改原数组。
forEach()方法不会返回执行结果、而是undefined,而且会修改原来的数组。而map()方法会得到一个新的数组并返回。

六、循环判断

1.every
array.every(function(currentValue,index,arr), thisValue) : 如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。

返回值:如果所有元素都满足条件,则返回 true。(A&B&C...)

2.some
array.some(function(currentValue,index,arr),thisValue) :如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。

返回值:如果没有满足条件的元素,则返回false。

3.every与some异同

相同:两者都不会对空数组进行检测,不会改变原始数组。
不同:
every()是对数组中每一项运行给定函数,如果该函数对每一项返回true,则返回true。   (A&B&C...)
some()是对数组中每一项运行给定函数,如果该函数对任一项返回true,则返回true。 (A || B || C...)

注意:
当判断条件为”不满足某条件“时,注意范围界定,因为等价的是 ! (A&B&C)(!A || !B || !C)。以下两段代码中的myFunction是等价的:

var ages = [32, 33, 16, 40];

function checkAdult(age) {
    return age >= 18;
}

function myFunction() {
    return ages.every(checkAdult)
}
var ages = [32, 33, 16, 40];

function checkNotAdult(age) {
    return age < 18;
}

function myFunction() {
    return !ages.some(checkNotAdult)
}

七、不完全遍历

1.forEach等遍历方法+内嵌 if 判断;
2.for (语句 1; 语句 2; 语句 3):利用某变量+语句2+语句3做控制;
3.当循环需要在”第一个满足某条件的元素“中终止时,可以利用every/some(推荐) 或 find/findIndex(仅ES6)做控制。

你可能感兴趣的:(js)