js中4種遍歷語法比較


前言:本文主要比較for、for-in、forEach和for-of的異同以及優缺點。

for

for循環是最原始最易理解的循環遍歷方式

for(var index = 0;index < arr.length;index++){
    console.log(arr[index])
}
  • 使用continue和break可以跳出本次循環和退出循環

forEach

上述for循環的寫法比較繁瑣,因此數組提供了內置的forEach方法

arr.forEach((item, index) => {
    consoel.log(item)
})

注意

  • forEach的寫法帶來了便利,但由於其每次循環實際上是一個回調函數,因此在函數內部無法用continue和break(用於循環)跳出循環
  • 可以用return跳出本次循環(相當於continue),而要退出循環只能拋出錯誤
var arr = [1,2,3]
arr.forEach((item) => {
    if (item === 2){
        return;// 跳出本次循環
    }
    console.log(item)
}
// 輸出1,3
try {
    arr.forEach((item) => {
    if (item === 2){
        throw new Error() // 退出循環
    }
    console.log(item)
})
} catch(e) {}
// 輸出1

for-in

for-in主要為遍歷對象而設計,也可以遍歷數組的鍵名。
for-in有幾個特點,通常情況下被認為是缺點:

  • 數組的鍵名是數字,但for-in循環是以字符串作為鍵名
var arr = ['a']
for(var item in arr){
    console.log(item, typeof item)
}
// 1, string
  • for-in循環無法保證對數組的遍歷順序(遍歷對象時也無法保證),由於數組是以鍵值對的形式存儲(詳情可見js的數組在內存中是如何存儲的),因此其無法保證遍歷順序的原因與遍歷對象一致,詳情可見js中對象的輸出順序
  • for-in會遍歷所有可枚舉屬性(包括原型鏈上的屬性),且由於js中數組是以鍵值對的形式存儲,因此數組的非索引屬性也會被遍歷
var arr = ['a', 'b']
Array.prototype.protoName = '原型屬性'
arr.name = '非索引屬性'
for(var item in arr){
    console.log(arr[item])
}
// a,b,'非索引屬性','原型屬性'

可以發現,for-in不僅遍歷了原型鏈上的屬性,新增的非索引屬性name頁被遍歷,因此for-in不適合遍歷數組。(由於length等屬性是不可枚舉屬性,因此沒有被遍歷)

  • for-in循環性能較差
    由於每次循環,for-in不僅會搜索實例屬性,還會搜索原型屬性,因此相比於其他循環方式,for-in的速度較慢。
var arr = new Array(10000)
for(var i=0;i< 10000;i++){
    arr[i]=i
}
var length = arr.length
console.time('for')
for (var index=0; index< length; index++){
    // 
}
console.timeEnd('for')
console.time('for-in')
for(var index in arr){
    //
}
console.timeEnd('for-in')
// for:0.2839ms
// for-in: 1.1479ms

因此,除非需要迭代一個屬性數量未知的對象,否則並不適合用for-in循環。
以上for-in的特性,在平常開發中共基本上都是缺點,但有一種可能算是優點的特性:for-in只會遍歷數組中存在的實體

var arr = new Array(3)
arr[2] = 'hello world'
var length = arr.length
for (var index=0; index< length; index++){
    console.log(arr[index])
}
// undefined,undefined, 'hello world'
for(var index in arr){
    console.log(arr[index])
}
// 'hello world'

可以看到for-in會忽略數組中為定義的部分,可以用於遍歷長度很大的稀疏數組。)

for-of

相比於以上幾點,for-of幾乎結合了它們的所有優點:

  • 有着for-in一樣簡單的語法,但沒有for-in的缺點
  • 不同於forEach,for-of可以使用break和continue跳出循環
  • 提供了遍歷所有數據結構的統一操作接口
  • 不僅支持對象和數組的遍歷,for-of支持一切可迭代對象的遍歷,包括類數組、字符串的遍歷;它將字符串視為一系列Unicode字符來遍歷。

但需要注意,普通對象不是可迭代對象,不能用for-of遍歷。想要迭代一個對象,可以用for-in,也可以將對象使用Map數據結構


免責聲明!

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



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