概念区分

  1. 循环(Loop):控制编程语句进入循环并重复执行同一段编程命令。如:while循环。
  2. 迭代(Iteration):指按照某种顺序逐个访问列表中的每一项(控制结构:重复结构)。核心是接近目标,新值覆盖旧值,空间利用率高。是一种特殊的遍历。如:for语句。
  3. 遍历(Traversal):按照一定的规则访问树形结构中的每个节点,每个节点只访问一次。如:vue中watch对data的深度监听。
  4. 递归(Recursion):程序调用自身(控制结构:选择结构)。核心是缩小范围,每调用一次就开辟一块栈空间,占用空间大。
以下介绍的方法都属于迭代。

方法

1 for

常用于遍历(迭代)数组、字符串。
可以控制循环起点或终点,其他方法只能从头开始。

1
2
3
4
let arr=[7,8,4,2];
for(let i=0;i<arr.length;i++){
console.log(arr[i]);//7 8 4 2
}

ES6之后使用let声明i,可以避免变量溢出。

2 for of (ES6)

常用于遍历(迭代)数组、字符串,以及带有iterator接口的对象,如:Array,Set,Map,String,TypedArray,arguments。
for of不能遍历对象。

1
2
3
4
let arr=['a','b','c'];
for(const i of arr){
console.log(i);//a b c
}

也可以用let声明i,区别只在于能否修改这个变量。
可以使用break,continue,return。

3 for in

常用于遍历(迭代)对象,遍历除Symbol以外的可枚举属性。

1
2
3
4
5
let obj={ name:'Luffy',title:'One Piece' };
for(let o in obj){
console.log(o);//name title
console.log(obj[o]);//Luffy OnePiece
}

如果用for in来遍历数组,输出的是数组的索引(下标)、对象的属性和原型链上的属性,一般不这样用。

1
2
3
4
let arr=[6,0,3];
for(let i in arr){
console.log(i);//0 1 2 entries keys values forEach length item
}

4 forEach

常用于数组、Map、Set,接收三个参数,无法使用break,continue,return跳出或中断循环,只能使用rtry catch中的throw抛出异常来停止,返回undefined,不改变原数组。
forEach不能遍历对象。
arr.forEach(function(value,index,arr){...},this);
三个参数只能按序添加,第一个参数必填,后面的参数和回调指向的this都可选。
所有的写法:

1
2
3
4
forEach(function(element) { /* … */ })
forEach(function(element, index) { /* … */ })
forEach(function(element, index, array){ /* … */ })
forEach(function(element, index, array) { /* … */ }, thisArg)
1
2
3
4
let arr=[5,6,4,5];
arr.forEach(function(element){
console.log(element);//5 6 4 5
})

配合箭头函数使用:箭头函数没有this,没有arguments,不能new。

1
2
3
4
5
6
let arr=[5,6,4,5];
arr.forEach((item,index,array)=>{
console.log(element);//5 6 4 5
});
//或
arr.forEach(item=>console.log(item));//5 6 4 5

5 map()

Array对象内置方法。不改变原数组,返回一个新数组。不对空数组检测。比forEach快。

1
2
3
4
5
let arr=[3,8,2,5,6];
let arr2=arr.map(function(oldValue,index,array){
console.log(oldValue);
return oldValue*2;
});//arr2:[6,16,4,10,12]

6 filter()

Array对象内置方法。不改变原数组,返回一个新数组,过滤符合条件的所有元素。不对空数组检测。

1
2
3
4
5
6
let arr=[5,0,3,6,9];
let arr2=arr.filter(function(oldValue,index,array){
return oldValue>=5;
},this);//arr2:[5,6,9]
//或箭头函数
let arr3=arr.filter(item=> item>=5 );//arr3:[5,6,9]

7 some()

Array对象内置方法。检测数组元素中是否有元素符合指定条件。不改变原数组。不对空数组检测。
如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。(不完全迭代)
如果没有满足条件的元素,则返回false。

1
2
3
4
5
6
let arr=[1,4,5,2];
let boo=arr.some(function(oldValue,index,array){
return oldValue<3;
},this);//true
//或箭头函数
let boo2=arr.some(item=> item<3 );//true

8 every()

Array对象内置方法。用于检测数组所有元素是否都符合指定条件。不改变原数组。不对空数组检测。
如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。(不完全迭代)
如果所有元素都满足条件,则返回 true。

1
2
3
4
5
6
let arr=[3,7,1];
let boo=arr.every(function(oldValue,index,array){
return oldValue==1;
},this);//false
//或箭头函数
let boo2=arr.some(item=> item==1 );//false

9 reduce() / reduceRight()

Array对象内置方法。将数组元素计算为一个值(reduce:从左到右,reduceRight:从右到左)。不改变原数组。不对空数组检测。

1
2
3
4
let arr=[4,0,6,8];
let res=arr.reduce(function(total,oldValue,index,arr){
return total+oldValue;
},0.5);//18.5

10 Array的其它内置方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let arr=[3,7,5,1];
let arr2=['ee','a2','y7'];

let obj=arr2.entries();//将数组转化为多个键值对的可迭代对象(Array Iterator对象),可以用for of打印出来。
//{{key:0,value:'ee'},{key:1,value:'a2'},{key:2,value:'y7'}}

let ele=arr.find(item=>item==5);//返回数组中符合条件的第一个元素,找到了则返回该元素,没找到返回undefined。
//5

let str="RED";
let arr3=Array.from(str);//将有length属性的对象或可迭代对象生成为一个数组
//['R','E','D']

let boo=arr.include(7);//判断数组是否包含某个值
//true
let boo2=arr.include(7,2);//从下标为2的位置开始检索,第二个参数默认为0,如果为负值则从length+index的位置开始检索
//false

let str2=arr2.join();//将数组所有元素转换为字符串
//ee,a2,y7

其它遍历方法:while, do while(属于循环)

End.🐧