天天看點

5 種 for 循環一次徹底搞懂

5 種 for 循環一次徹底搞懂

for 循環在平時開發中使用頻率最高的,前後端資料互動時,常見的資料類型就是數組和對象,處理對象和數組時經常使用到 for 周遊,是以下班前花費幾分鐘徹底搞懂這 5 種 for 循環。它們分别為:

  • for
  • for ... in
  • for ... of
  • for await .. of
  • forEach
  • map

一、各個 for 介紹

1、for

for 循環是出現最早,也是應用最普遍的一個周遊,能夠滿足絕大多數的周遊。可以周遊 數組、對象、字元串,示例:​

// 周遊數組
var arr = [1, 2, 3]
for (var i = 0; i < arr.length; i++){
  console.log(arr[i]);
}
//周遊對象
var obj = {
  job: 'web worker',
  name:'前端代碼女神'
}
for (var i = 0,keys = Object.keys(obj); i< keys.length; i++){
  console.log(obj[keys[i]])
}


//周遊字元串
let str = 'abc'
for (var i = 0; i < str.length; i++){
  console.log(str[i])
}      
2、for ... in

for ... in 是在 ES5 中新增的,以任意順序疊代一個對象的除Symbol以外的可枚舉屬性,包括繼承的可枚舉屬性。

// 周遊數組
var arr = [1, 2, 3]
for (var i in arr ){
  console.log(i);//0 1 2
  console.log(arr[i]);//1 2 3
}
//周遊對象
var obj = {
  job: 'web worker',
  name:'前端代碼女神'
}
for (var key in obj){
  console.log(key)// job name
  console.log(obj[key])// web worker  前端代碼女神
}
//周遊字元串
let str = 'abc'
for (var i in str){
  console.log(i) // 0 1 2
  console.log(str[i]) // a b c
}      
3、for ... of

for ... of 語句在可疊代對象(包括 Array、Map、Set、String、TypedArray、arguments 對象等等)上建立一個疊代循環,調用自定義疊代鈎子,并為每個不同屬性的值執行語句。​

// 疊代 Array
var arr = [1, 2, 3]
for (var val of arr ){
  console.log(val);// 1 2 3
}
//疊代 String
let str = 'abc'
for (var val of str){
  console.log(val) // a b c
}
// 疊代 TypedArray - 一個類型化數組,描述了一個底層的二進制資料緩沖區!
let iterable = new Uint8Array([0x00, 0xff]);


for (let value of iterable) {
  console.log(value);//0 255
}
// 疊代 Map - 對象儲存鍵值對,能夠記住鍵的原始插入順序
let map = new Map([['a',1],['b',2]])
for (let key of map) {
  console.log('key',key)//['a',1] ['b',2] 
}
for (let [key,value] of map) {
  console.log(key) // a b
  console.log(value) // 1 2
}
// 疊代 Set
let set = new Set([1,2,3,2,1])
for (let val of set) {
  console.log(val)// 1 2 3
}      
4、for await...of

建立一個循環,該循環周遊異步可疊代對象以及同步可疊代對象,包括内置的 String、Array,類數組對象(arguments 或 nodeList),TypedArray, Map, Set 和使用者定義的異步/同步疊代器。

它使用對象的每個不同屬性的值調用要執行的語句來調用自定義疊代鈎子。

類似于 await 運算符一樣,該語句隻能在一個async function 内部使用。

async function* asyncGenerator() {
  var i = 0;
  while (i < 3) {
    yield i++;
  }
}
(async function () {
  for await (num of asyncGenerator()) {
    console.log(num);// 0 1 2
  }
})();      
5、forEach

forEach 是ES5版本釋出的,按升序為數組中含有效值的每一項執行一次回調函數,那些已删除或者未初始化的項将被跳過(例如在稀疏數組上),一般認為是 普通for循環 的加強版。

// 周遊數組
var arr = [1, 2, 3]
arr.forEach((item, index) => {
  console.log(index);//0 1 2
  console.log(item);// 1 2 3
})
//周遊對象
var obj = {
  job: 'web worker',
  name:'前端代碼女神'
}
var keys = Object.keys(obj)
keys.forEach((key) => {
  console.log(key)// job name
  console.log(obj[key])// web worker  前端代碼女神
})      
6、map

周遊時可以傳回一個新數組,新數組的結果是原數組中每個元素都調用一次提供的函數後傳回的值。

// 周遊數組
var arr = [1, 2, 3]
let newArr = arr.map((item) => item * 2)
console.log(newArr);//[2,4,6]      

二、多個 for 之間差別

1、使用場景差異

for循環是最早最原始的循環周遊語句,for 内部定義一個變量,按照條件進行循環周遊,通常是數組的長度,當超過長度時就停止循環,一般周遊的都是數組或類數組。

周遊對象時,由于對象沒有長度,是以使用 Object.keys() 擷取對象的所有屬性,以數組形式傳回。

for / in主要是用來周遊對象上的可枚舉屬性,包括原型對象上的屬性,按任意順序進行周遊,周遊對象時擷取到的是屬性的鍵值,周遊的是數組,數組的下标當做鍵值。

for / of用于周遊可疊代對象的資料,包括 Array、Map、Set、String、TypedArray、arguments 對象等等。

for await...of用于周遊異步可疊代對象,該語句隻能在一個async function 内部使用。

f orEach 是 for 的加更新版,使用更簡單,攜帶參數更多,但本質還是數組的循環,每個元素都執行一次回調,不會改變原數組。

map是給原數組每個元素都執行一次回調,傳回一個新數組,不會改變原數組。

2、功能差異

forEach、map 不支援跳出循環,其他不支援。

for await ... of 能夠支援異步操作,其他的不支援。

對于純對象的周遊, for ... in 枚舉更友善。

對于數組周遊,如果不需要索引,可以直接使用 for...of 擷取值,還可支援 break 或 return ;如果還需要索引,使用 forEach 更适合,但不支援 return。

如果是一個數組映射成另一個數組,使用 map 最合适。

3、性能差異

在測試環境、測試資料條件一緻的情況下,性能排序為:

for > for of > forEach > map > for in。

for 因為沒有額外的函數調用和上下文,是以性能是最快的。

for ... of 具有 iterator 接口的資料結構,可以使用它來疊代成員,直接讀取鍵值。

forEach 是 for 的文法糖,還有許多的參數和上下文,是以會慢一些。

map 因為它傳回的是一個等長的全新數組,數組建立和指派産生的性能開銷較大。

for...in 性能最差,因為需要列舉對象的所有屬性,有轉化過程,開銷比較大。

三、for 的使用

在項目開發中,我們應該根據實際需求,去選擇一個合适的 for 周遊。以下是一些使用建議:

  1. 如果需要把資料映射成另外一個數組,如變成對應布爾值,推薦使用 map ,不會修改原數組,使用文法簡單。
  2. 數組周遊時,可以使用 for 、forEach 或 for...of。
  3. 周遊的是純對象時,推薦使用 for ... in 。
  4. 如果是需要對疊代器周遊,推薦使用 for ... of。
  5. 如果是在數組中篩選符合條件的數組,使用 fillter 。

學習更多技能

請點選下方公衆号