for in 與for of循環的區別

最近看了一篇google的js編碼規範,在ES6中,有3種不同的for循環。儘管每一種有它的應用場景,但Google仍推薦使用for…of。不過我喜歡使用for…in遍歷Object,使用for…of遍歷數組。for…of是ES6新引入的特性。修復了ES5引入的for…in的不足。儘管這種使用方式與google的規範相沖突,但我就喜歡這種各司其職的使用方式,讓我們來對for…in和for…of做一個分析,對比分析過後,喜歡用那種方式就那種方式,都不影響的。無論是for…in還是for…of語句都是迭代一些東西。它們之間的主要區別在於它們的迭代方式。for…in 語句以原始插入順序迭代對象的可枚舉屬性(只能迭代出可枚舉的屬性,至於什麼叫做可枚舉屬性/不可枚舉屬性,請baidu/google)。for…of 語句遍歷可迭代對象定義要迭代的數據(非自定義屬性)。下面我們來看一下:

如果我們要遍歷一個數組的value值,我們定義這個數組:

 let arr = ['a','b','c'];

我們先使用for in 循環:

for(let index in arr ){
    console.log(`${arr[index]}`);//a,b,c
}

在使用for of 循環

for(var value of arr){
    console.log(value);//a,b,c
}

看上去好像只有寫法不一樣而已,但是爲什麼說for of 補充了for in 的缺陷呢,我們往數組arr裏添加一個hobby屬性。

arr.hobby = 'foosball';

現在我們再使用這兩種方式對數組進行遍歷輸出:

for(let index in arr){
    console.log(`${arr[index]}`); //a,b,c,'foosball'
}
for(var value of arr){
    console.log(value);//a,b,c
}

這裏就很明顯了。for…of不能循環出自定義的屬性。我們再換一種方式,代碼如下:

Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {};
arr.hobby = 'foosball';

for (let i in arr) {
  console.log(i); // 0, 1, 2, "hobby", "arrCustom", "objCustom"
}

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); //0, 1, 2, "hobby"
  }
}

for (let i of iterable) {
  console.log(i); // 'a', 'b', 'c'
}

將objCustom屬性和arrCustom屬性添加到Object.prototype和Array.prototype。由於繼承和原型鏈,對象arr繼承屬性objCustom和arrCustom。使用hasOwnProperty() 來檢查,證明屬性arrCustom和objCustom是繼承的。由此可見,for…of循環的是的是可迭代對象的value(值),in循環的是可迭代對象的key(屬性),for…of循環不能循環普通的對象,對普通對象的屬性遍歷推薦使用for…in。
但是非要使用for…of來循環對象,並不是不可以。此時就要結合Object.keys()進行使用:

for(var key of Object.keys(arr)){
    //使用Object.keys()方法獲取對象key的數組
    console.log(arr[key]);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章