JavaScript中for of和for in的差別
前言
JavaScript遍歷資料的方法有相當多種,本身資料若是陣列,甚至還有.forEach
及.map
可以使用
主要功能都是遍歷數組,但在可讀性上會有較佳的感受。當然使用上也略有不同
不論採用哪種遍歷資料,都比最基礎的for(let i = 0;i < arr.length;i++)
來得優美許多
本篇針對最容易搞混的for in
、for of
說明
for in
vs for of
主要差別如下:
for in
是ES5標準;for of
是ES6標準。for of
修復for in
的不足- 用object來說的話,
for in
遍歷的是key;for of
遍歷的是value。不過JavaScript中object本身不是可迭代對象,for of
會直接報錯(object迭代寫法後面再說明) for of
不能遍歷一般物件,主要是針對數組(即array、arguments等可迭代的對象)使用,會忽略掉不可遍歷的對象for of
可使用的對象有Array
、Map
、Set
、String
、TypedArray
、arguments
for in
會遍歷自定義屬性,甚至原型鏈上的屬性也會遍歷到,反而又不是我們所想要的
.forEach
同時是在ES5中引進的用法,個人猜想當初設計的想法應該是:
數組要取value的話用.forEach
,要取key的話用for in
來取代最原始的for(let i = 0;i < arr.length;i++)
寫法。分成兩種取法避免掉使用Object.key()
這種比較複雜的寫法,從而精簡語意
但.forEach
僅能做單純的遍歷,不可以配合continue
、break
、return
等語句,在實務上又沒那麼好用
而用for in
遍歷衍生不少問題,最後只好針對for in
又推出了修正版本的for of
以上只是個人的推測,若有錯誤煩請告知
直接上程式碼
let arr = ['a','b','c','d',{'e':'e_value','f':'f_value'}];
for(let index in arr){
console.log(index);
}
// 0,1,2,3,4
//---------------------------------------------------
//若想要用for in 取value,也是可以
for(let index in arr){
console.log(arr[index]);
}
//a,b,c,d,{'e':'e_value','f':'f_value'}
//---------------------------------------------------
//for in 會遍歷自定義屬性
arr.name='myArray';
for(let index in arr){
console.log(index);
}
// 0,1,2,3,4,name
//若寫console.log(arr[index]),自定義的name則會印出其內容'myArray'
//---------------------------------------------------
//但用for of,則可以寫的更優雅。且不會遍歷自定義屬性
for(let value of arr){
console.log(value);
}
//a,b,c,d,{'e':'e_value','f':'f_value'}
object 遍歷方法
前文可以看到for of
修正了for in
的問題,同時解決array中.forEach
限制的continue
、break
但在JavaScript中,除了陣列,最常使用的就是object
了!
直接將for of
套用在object中,卻發現直接報錯!因為object本身不是一個可迭代的對象,所以無法遍歷!
這時候就要配合Object.keys()
來做了
let obj = {
a:'a_value',
b:'b_value',
c:'c_value'
}
for(let key of Object.keys(obj)){
console.log(obj[key]);
}
//a_value,b_value,c_value
但這樣寫就太過冗長,不如就直接用for in
來做
而這也是for in
的主要工作
for(let idx in obj){
console.log(obj[idx]);
}
//a_value,b_value,c_value
延伸:陣列內含object的寫法
若您的資料結構較複雜,有一堆object組合而成的陣列,想要遍歷陣列裡的物件的value
這又該怎麼寫呢?
就要結合for in
跟for of
了!
let complexArray = [
{
name:'小明',
birth:'1995/07/01'
},
{
name:'小美',
birth:'1989/11/17'
},
{
name:'小帥',
birth:'1990/06/25'
}
]
for(let obj of complexArray){ //先遍歷出所有物件
for(let key in obj){ //再遍歷每一物件的key,取得value
console.log(obj[key]);
}
}
//小明,1995/07/01,小美,1989/11/17,小帥,1990/06/25
當然實務上不是只有單純的遍歷印出就好
這大概只有在將資料輸出成一份總表才有可能用上
若得到的數組資料後,還要先行過濾一些條件,再產生結果
只要將console.log(obj[key]);
根據業務需求放入條件,回傳需要的結果就行了!
//比如列出6月出生的的人物資料
//日期判斷偷懶直接用正則表達來做,實務上配合moment.Js可以做得更好,好讀又易理解
for(let obj of complexArray){ //先遍歷出所有物件
for(let key in obj){ //再遍歷每一物件的key,取得value
if(key=='birth')
if(obj['birth'].match(/\d{4}\/06\/\d{2}/))
console.log(obj);
}
}
//以此題為例,只需要判斷其中日期,遍歷所有key其實很浪費資源又浪費時間
//若已知是針對日期(或其他key的內容)做判斷的話,其實只需要for of就夠了
//直接將要判斷key寫上去,不但增加可讀性、少跑一次迴圈、又好理解(一樣,日期方面配合moment.Js更佳)
for(let obj of complexArray){
if(obj['birth'].match(/\d{4}\/06\/\d{2}/))
console.log(obj);
}
//{name:'小帥',birth:'1990/06/25'}
後記
每次從Python回來再寫JavaScript的時候,都會搞混然後又要再Google一次…
因為Python是用for in
而JavaScript上大部份情況用for of
較佳,但有的時候又會回來用for in
…