for/for..in/for..of/forEash的用法和区别

934 阅读3分钟

for

  • 循环集合或数组

  • 对于数组空值,不会跳过

array = ['a', , 'c']

for (let i = 0; i < array.length; i++) {
    console.log(array[i]) // a undefined c // 没有跳过空值
}

值得注意的是,如果空值明确设置为undefined或者null,如 ['a',undefined,'c']['a',null,'c'],那么所有遍历方法都能将其遍历出来

  • 可以break;continue;
for (let i = 0; i < array.length; i++) {
    if(array[i]==='a'){
        break;
        // continue;
    }
    console.log(array[i])
}
  • 数组进行添加更新删除操作,可以遍历新数组

使用

  1. 适用于复杂的循环,在复杂循环中效率高

for..in

  • 用于遍历数组或者对象的可枚举属性。

循环语句将返回所有可枚举属性,包括非整数类型的名称和继承的那些。

for(let key in ['2','3',4]){
   console.log(key)// 0 1 2
}

for(let key in {"name":"yang","age":12}){
   console.log(key)// name age
}

其他可枚举属性都会遍历出来,在js中,数组也是对象,数组索引只是具有整数名称的枚举属性,并且与通用对象属性相同,数组也可以添加字符串属性。

数组所添加的字符串属性,只有for...in能打印出来。

Object.prototype.objCustom = function(){}
Array.prototype.arrCustom = function(){}
let iterable = [3,5,7]
iterable.foo = 'hello'
for(let key in iterable){
    console.log(key) //0 1 2 foo arrCustom objCustom
}

也可遍历一段字符串

for(var key in "2344dkgjls"){
   console.log(key) // 0 1 2 3 4 5 6 7 8 9 
}
  • 对于数组空值,会跳过
array = ['a', , 'c']

for (const key in array) {
    console.log(array[key]) // a c // 跳过空值
}
  • 可以break;continue;
for (let key in array) {
    if(array[key]==='a'){
        break;
        // continue;
    }
    console.log(array[key])
}
  • 返回的属性具有无序性,不可预测。

缺点:会遍历自定义添加的属性,原型上的属性。

使用

  1. 常用于遍历对象

  2. 不建议遍历数组,除非清楚的知道这个数据没有字符串属性。

for..of

这是ES6引进的新语法。

  • 遍历可迭代对象定义要迭代的数据(可迭代对象包括:Array, Map, Set, String, TypeArray, arguments)

for(let key of "2344dkgjls"){
   console.log(key) // 2 3 4 4 d k g j l s
}

Object.prototype.objCustom = function(){}
Array.prototype.arrCustom = function(){}
let iterable = [3,5,7]
iterable.foo = 'hello'
for(let key of iterable){
    console.log(key) //3 5 7
}
  • 不可迭代对象
let obj = {1:"Saab", 2:"Volvo", 3:"BMW"};
 
obj.color = "white"
 
for (let key of obj)
{
   console.log(key);
}

// 报错 obj is not iterable
  • 对于数组空值,不会跳过
array = ['a', , 'c']

for (let key of array) {
    console.log(key) // a undefined c// 没有跳过空值
}
  • 能break,continue
for (let key of array) {
    if(key==='a'){
        break;
        // continue;
    }
    console.log(key)
}

缺点:不遍历普通对象,会报错不支持迭代

使用:常用于遍历数组

forEash

  • 数组的原型方法,像是对for的包装,只进行数组遍历

  • 对于数组空值,会跳过

array = ['a', , 'c']

array.forEach(key => {
    console.log(key) // a c// 跳过空值
})
  • 不能break;continue;会报错。
array.forEach(key => {
    if(key === '1'){
        break;
    }
    console.log(key)
})
  • 遍历的时候,无法对数组进行添加更新删除操作
let array = ['1','a','c','b']
array.forEach((val, i) => {
    if(val == '1') {
         array.splice(i,1)
    }
    //  ['a','c','b']
    console.log(array, '   forEach')
    // 1 虽然删除了,仍然可以打印出来
    console.log(val, '   forEach')
})

array.forEach((val, i) => {
    if(val == '1') {
        val = 100
    }
    // ['1','a','c','b'] // 数组不变
    console.log(array, '   forEach')
})

总结

for

  • 循环语句,对元素依照顺序进行循环,结构复杂,用于处理复杂的程序逻辑
  • 对于数组空值,不会跳过
  • 可以break,continue
  • 遍历时,可对数组进行更新删除添加等操作
  • 不可循环对象

forEach

  • Array原型方法,只遍历数组,像是for的包装,可以处理简单的数组逻辑
  • 对于数组空值,会跳过
  • 不可以break,continue
  • 遍历时,不可对数组进行更新删除添加等操作

for...in

  • 用于遍历数组或者对象的可枚举属性。(可遍历Object,Array,String)
  • 对于数组空值,会跳过
  • 可以break,continue
  • 返回的属性具有无序性,不可预测。
  • 不建议遍历数组,除非清楚知道数组没有其他的属性

for...of

  • 遍历可迭代对象定义要迭代的数据(可遍历Map,Set,Array,String)
  • 对于数组空值,不会跳过
  • 可以break,continue,return
  • 不可遍历对象,会报错