徹底搞懂並會用數組之循環


  最近做了一個新項目,閑暇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()  「推薦使用這個」


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM