最近做了一個新項目,閑暇review了下代碼,發現自己用了很多for循環(簡潔明了),再看下別人的代碼幾乎沒有for,幾乎全是foreach和map循環,難道是我寫的太low了嗎?其實在寫碼的時候有時候也有選擇恐慌症,到底該用哪種循環,最后發現其他方法總是不能為我所用,最后總是選擇了最簡單的for,怎一個好用了得,也早想花點時間好好研究比較一下數組的這些循環方法,下面就開始正文啦!
1. 在ES5中常用的10種數組遍歷方法:
1、for循環語句
2、Array.prototype.forEach數組對象內置方法
3、Array.prototype.map數組對象內置方法
4、Array.prototype.filter數組對象內置方法
5、Array.prototype.reduce數組對象內置方法
6、Array.prototype.some數組對象內置方法
7、Array.prototype.every數組對象內置方法
8、Array.prototype.indexOf數組對象內置方法
9、Array.prototype.lastIndexOf數組對象內置方法
10、for...in循環語句
1. for:簡潔明了,通俗易懂,可能需要多寫點代碼,多定義幾個變量,但是為我所用,為我所愛。
「普通版」
let arr = [1, 2, 3, 4, 5];
for(let i = 0; i < arr.length; i++) {
arr[i] = arr[i] * 2;
}
console.log(arr); //[2, 4, 6, 8, 10]
「加強版」
let arr = [1, 2, 3, 4, 5];
for(let i = 0; len = arr.length,i < len; i++) {
arr[i] = arr[i] * 2;
}
console.log(arr); //[2, 4, 6, 8, 10]
2. forEach:接收兩個參數,第一個參數是在每一項上運行的函數(擁有三個參數),第二個參數「可選的」是運行該函數的作用域對象(影響this的值),return不能中斷函數繼續執行,所以沒有返回值,不能改變原數組,使用方便一般涌來代替for,但是沒for性能高,而且有兼容性(IE6-8)。
let arr = [1, 2, 3, 4, 5];
arr.forEach((value, index, array) => {
return value * 2;
});
console.log(arr); //[1, 2, 3, 4, 5]
3. map:基本用法和foreach相同,不同的是可以return返回值,但是不改變原數組,一般用來修改數組的值從而映射為一個新數組。
let arr = [1, 2, 3, 4, 5];
let arrs = arr.map((value, index, array) => {
return value * 2;
});
console.log(arrs); //[2, 4, 6, 8, 10]
4. filter:顧名思義是"過濾",就是去掉不想要的值,return true為想要的值,return false則為去掉的值,一般用來過濾一個數組,不改變原來的數組。
let arr = [1, 2, 3, 4, 5];
let arrs = arr.filter((value, index, array) => {
if (value > 2) {
return true;
} else {
return false;
}
});
console.log(arrs); //[3, 4, 5]
5. reduce:可以實現一個累加器的功能,將數組的每個值(從左到右)累加起來,不同的是有四個參數,prev表示前兩個值的和(沒有定義初始值時為第一個值),next為后一個值。
let arr = [1, 2, 3, 4, 5];
let arrs = arr.reduce((prev, next, index, array) => {
console.log(prev); // 1,3,6,10
console.log(next); // 2,3,4,5
return prev + next;
});
console.log(arrs); //15
6. some:類似於filter,不同的是返回值為Boolean,不是篩選一個新的數組,而是篩選有沒符合條件的值,只要有一個值滿足即立刻返回true,不再繼續執行,否則返回false。
let arr = [1, 2, 3, 4, 5];
let arrs = arr.some((value, index, array) => {
return value > 3;
});
console.log(arrs); // true
7. every:類似於some,不同的是找到符合條件的值會繼續執行,如果每個值都滿足條件才會返回true,否則就是false。
let arr = [1, 2, 3, 4, 5];
let arrs = arr.every((value, index, array) => {
return value > 3;
});
console.log(arrs); //false
let arr = [ 4, 5];
let arrs = arr.every((value, index, array) => {
return value > 3;
});
console.log(arrs); //true
8. indexOf:數組中的這個方法和字符串中的幾乎一樣,都是找到一個滿足條件的值就不繼續執行了,返回值是滿足條件值的下標,否則返回-1。
let arr = [1, 2, 3, 4, 5]; let arrs = arr.indexOf(2); console.log(arrs); // 1 let arr = [1, 2, 3, 4, 5]; let arrs = arr.indexOf(6); console.log(arrs); // -1
9. lastIndexOf:類似於indexOf,不同的是查找方向是從后向前。
let arr = [1, 2, 3, 4, 5, 1]; let arrs = arr.lastIndexOf(1); console.log(arrs); // 5 let arr = [1, 2, 3, 4, 5, 1]; let arrs = arr.lastIndexOf(6); console.log(arrs); // -1
10. for...in:主要用來遍歷對象,其實數組的本質也是以key和value的鍵值對存在的,數組遍歷的是下標,對象遍歷的是key,一般用來遍歷對象。
let arr = [1, 2, 3, 4, 5];
for(let i in arr) {
console.log(i); // 0, 1, 2, 3, 4
}
let arr = {name: "lewis", age: 25};
for(let i in arr) {
console.log(i); // name, age
}
2. 在ES6中常用的for...of數組遍歷方法:
for...of: JavaScript 原有的for...in循環,只能獲得對象的鍵名,不能直接獲取鍵值。ES6 提供for...of循環,允許遍歷獲得鍵值,但是不能循環對象,一般用來循環數組。
let arr = [1, 2, 3, 4, 5];
for (let i in arr) {
console.log(i); // 0, 1, 2, 3, 4
}
for (let i of arr) {
console.log(i); // 1, 2, 3, 4, 5
}
看到這里相信你已經把基本用法和示例弄的差不多了,接下來總結一下,一般的循環用for,for...in,for...of和forEach,需要映射為新數組的用map,需要篩選出想要的用filter,數值需要進行累加的用reduce,如果要找一些值用some和every,並且想知道值的具體位置的可以用indexOf和lastIndexOf,接下來就是對症下葯,因地制宜了,相信你會熟練掌握並准確應用了。
3. 常用的一般數組循環for,for...in,for...of和forEach/map性能對比:
let arr = Array(100).fill(5);
console.time("for循環");
for(let i = 0; i < arr.length; i++) {
arr[i] = arr[i] * 2;
}
console.timeEnd("for循環"); // for循環: 0.041ms
console.time("for...in循環");
for(let i in arr) {
arr[i] = arr[i] * 2;
}
console.timeEnd("for...in循環"); // for...in循環: 0.126ms
console.time("for...of循環");
for(let i of arr) {
arr[i] = arr[i] * 2;
}
console.timeEnd("for...of循環"); // for...of循環: 3532.695ms
console.time("forEach循環");
arr.forEach((value, index, arr) => {
arr[index] = value * 2;
});
console.timeEnd("forEach循環"); // forEach循環: 0.103ms
console.time("map循環");
arr.map((value, index, arr) => {
arr[index] = value * 2;
});
console.timeEnd("map循環"); //map循環: 0.086ms
哈哈,經過多次對比取平均值可以明顯的看到for循環秒殺其他方法(這只是100個數,如果更多的數效果將會更明顯),原來自己的方法一點都不low啊,只要在正確的場合應用正確的方法並簡單有效才是最好的,以后一般的循環大家可以大膽的使用for循環啦!
常用的檢測數組的方法(額外福利):
1. instanceof
2. Array.isArray()
3. Object.prototype.toString.call() 「推薦使用這個」
