js中4种遍历语法比较

前言:本文主要比较for、for-in、forEach和for-of的异同以及优缺点。html

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等属性是不可枚举属性,所以没有被遍历)spa

  • 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只会遍历数组中存在的实体prototype

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几乎结合了它们的全部优势:code

  • 有着for-in同样简单的语法,但没有for-in的缺点
  • 不一样于forEach,for-of可使用break和continue跳出循环
  • 提供了遍历全部数据结构的统一操做接口
  • 不只支持对象和数组的遍历,for-of支持一切可迭代对象的遍历,包括类数组、字符串的遍历;它将字符串视为一系列Unicode字符来遍历。

但须要注意,普通对象不是可迭代对象,不能用for-of遍历。想要迭代一个对象,能够用for-in,也能够将对象使用Map数据结构htm

相关文章
相关标签/搜索