JS常用的循环遍历和它们的特性

11 篇文章 0 订阅
8 篇文章 0 订阅

JS常用的循环遍历

for、forEach、for …of for…in

  1. for

    通常用于数组的循环 可以随时跳出循环,用break或者continue

    const list = [1, 2, 3, 4, 5, 6, 7, 8, , 10, 11];
    let len = list.length;
    for (let i = 0; i < len; i++) {
        if (list[i] === 5) {
        //   break; // 1 2 3 4
          continue; // 1 2 3 4 6 7 8 undefined 10 11
        }
        console.log(list[i]);
      }
    
  2. forEach

    可以对循环的元素做一些特定的操作,回调函数的参数更丰富,元素,索引和原数组都可以获得。

    forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

    注意: forEach() 对于空数组是不会执行回调函数的。

    回调函数的语法如下:

    array.forEach(function(currentValue, index, arr), thisValue)

    其中 第一个参数为回调函数function(currentValue, index, arr) ,currentValue 是必须的,表示当前的正在遍历的元素,index和arr是可选的,分别表示当前元素的索引以及当前元素所属的数组对象

    第二个参数thisValue是可选的,传递给函数的值一般用this值,如果这个参数为空,undefined,会传递给this

    const list = [1, 2, 3, 4, 5, 6, 7, 8, , 10, 11];
    let len = list.length;
    let result = []
    list.forEach(function(cur,index,arr){
        console.log(`当前元素为${cur},索引为${index},所属数组为${arr}`);
        result.push(cur*2);
    })
    
    console.log(result); //[ 2,  4,  6,  8, 10, 12, 14, 16, 20, 22]
    
    let rest = []
    rest.forEach(function(cur){
       console.log("我没有执行啊~~,因为我是空数组"); 
    })
    

    注意:forEach 无法跳出循环,一旦执行了,除非抛出错误,否则会一直执行下去,直到数组的最后一个元素。

    不支持 continue,用 return false 或 return true 代替。

    var arr = [1, 2, 3, 4, 5];
    arr.forEach(function (item) {
        if (item === 3) {
            return;
        }
        console.log(item); //1 2 4 5
    });
    

    不支持 break,用 try catch/every/some 代替:

    返回值: undefined

      const list = [1,2,3,4]
    const result = list.forEach(function(cur){
         return cur
     })
     console.log(result); //undefined
    
  3. for in

    1. 获取enumerable:true的属性键。

    2. 可以遍历对象(这时候获得是对象的键)和数组(数组的索引)。

    3. 可以获取原型上的属性键。

    4. 数字属性键被遍历出来是字符串。比如索引值

    5. 不可以跳出循环

    const list = [1, 2, 3, 4, 5, 6, 7, 8, , 10, 11];
    let len = list.length;
    
    //1. 对于数组
    for(const k in list){
        // console.log(k); //[0,1,2,3,4,5,6,7,8,9,10]  //k 是索引
        console.log(list[k]); //[1,2,3,4,5,6,7,8,10,11] //忽略空元素
        if(k===5){  //不会退出
            break;
        }
    }
    
    
    Object.prototype.fun = () => {};
    const obj = { 2: 'a', 1: 'b' };
    for (const i in obj) {
      console.log(i, ':', obj[i]);
    }
    // 1: b
    // 2: a
    // fun : () => {} Object 原型链上扩展的方法也被遍历出来
    
    for (const i in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, i)) {
          console.log(i, ':', obj[i]);
        }
    }
    
    //1 : b
    //2 : a
    
    
    // fun不属于自身的属性将被 hasOwnProperty 过滤
    

    注意:

    使用 for in 循环时,返回的是所有能够通过对象访问的、可枚举的属性,既包括存在于实例中的属性,也包括存在于原型中的实例。如果只需要获取对象的实例属性,可以使用 hasOwnProperty 进行过滤

    使用时,要使用 (const x in a) 而不是 (x in a) 后者将会创建一个全局变量。

    遍历的顺序会因为浏览器的不同而不同

  4. for of:

    1. 遍历属性值。不受到enumerable限制。

    2. 可遍历数组。一般不可以遍历对象,如果实现了Symbol.iterator,可以遍历。如Array,Map,Set,String,TypedArray,arguments 对象等等

    3. 不能获取原型上的值

    4. 可以用break退出循环和continue跳过循环

    5. for …of 直接访问的是实际元素

    6. 如果遇到空元素同样会执行

    const list = [1, 2, 3, 4, 5, 6, 7, 8, , 10, 11];
    let len = list.length;
    
    //1. 对于数组
    for(const v of list){
        //  console.log(v); //[1,2,3,4,5,6,7,8,undefined,10,11]  //v 是元素的值  不会忽略空元素 
         if(v === 7) break; //允许退出  continue也有有效
         console.log(v);//[1,2,3,4,5,6]  
         
    }
    
    
    // 2 对于对象
    // 原型上增加方法
    Array.prototype.gogo = function(){
        console.log("gogo");
    }
    
    var a = [1,2,3];
    
    // key值2不可以枚举
    Object.defineProperty(a, 2, {
        enumerable: false
    });
    Object.defineProperty(a, "2", {
        enumerable: false
    });
    
    for(let p in a){
        // 索引被遍历出来是字符串类型
        console.log(p, typeof p); // 0 string; 1 string; gogo string
    }
    
    console.log("---")
    
    for(let v of a){
        console.log(v);  // 1 2 3
    }
    

some every

  1. some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。

    some() 方法会依次执行数组的每个元素:

    • 如果有一个元素满足条件,则表达式返回true ,剩余的元素不会再执行检测
    • 如果没有满足条件的元素,则返回false。

    注意: some() 不会对空数组进行检测

    注意: some() 不会改变原始数组

    some语法:

    array.some(function(currentValue,index,arr),thisValue)

    和forEach类似

    注意:

    返回值: 布尔值。如果数组中有元素满足条件返回 true,否则返回 false。

     const list = [
        { name: '头部导航', backward: false },
        { name: '轮播', backward: true },
        { name: '页脚', backward: false },
      ];
     const someBackward = list.some(item => item.backward);
    console.log(someBackward);//true
     
     const arr = [1,2,3,4]
     const result =arr.some(function(item){
         if(item===5) return true;
     })
    
     console.log(result); //false
     
    
  2. every

    every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。

    every() 方法使用指定函数检测数组中的所有元素:

    • 如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
    • 如果所有元素都满足条件,则返回 true。

    注意: every() 不会对空数组进行检测

    注意: every() 不会改变原始数组

    返回值:布尔值。如果所有元素都通过检测返回 true,否则返回 false。

const list = [
    { name: '头部导航', backward: false },
    { name: '轮播', backward: true },
    { name: '页脚', backward: false },
  ];

  const everyNewest = list.every(item => !item.backward);
 console.log(everyNewest); //false

 const arr = [1,2,3,4]
 const result =arr.every(function(item){
     if(item>3) return true;
 })
 console.log(result); //false
 

 const result2 =arr.every(function(item){
    if(item<5) return true;
})
console.log(result2); //true

比较

  • 二者都是用来做数组条件判断的,都是返回一个布尔值。
  • 二者都可以被中断。
  • some 若某一元素满足条件,返回 true,循环中断。所有元素不满足条件,返回 false。
  • every 与 some 相反,若有一元素不满足条件,返回 false,循环中断。所有元素满足条件,返回 true。

filter、map

  1. filter

    filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

    注意: filter() 不会对空数组进行检测。

    注意: filter() 不会改变原始数组。

    语法:array.filter(function(currentValue,index,arr), thisValue) 与forEach类似

    返回值:返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组。

  2. map

    map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

    map() 方法按照原始数组元素顺序依次处理元素。

    注意: map() 不会对空数组进行检测。

    注意: map() 不会改变原始数组。

    语法:array.map(function(currentValue,index,arr), thisValue)

    **返回值:**返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

比较:

  • 二者都是生成一个新数组,都不会改变原数组(不包括遍历对象数组时,在回调函数中操作元素对象)。
  • 二者都会跳过空元素。
  • map 会将回调函数的返回值组成一个新数组,数组长度与原数组一致
  • filter 会将符合回调函数条件的元素组成一个新数组。
  • map 生成的新数组元素可自定义。
  • filter 生成的新数组元素不可自定义,与对应原数组元素一致。
const list = [
    { name: '头部导航', type: 'nav', id: 1 },  
    ,
    { name: '轮播', type: 'content', id: 2 },
    { name: '页脚', type: 'nav', id: 3 },
    ];
    const resultList = list.filter(item => {
      return item.type === 'nav';
    });
    console.log(resultList);  //跳过空元素
    //输出:
    //[
    //   { name: '头部导航', type: 'nav', id: 1 },
    //   { name: '页脚', type: 'nav', id: 3 },
    // ]
    
    const newList = list.map(item => {
      console.log(item);
      return item.id;
    });
    console.log(newList);  //[1, , 2, 3] //跳过空元素

find、findIndex

  1. find

    find() 方法返回通过测试(函数内判断)的数组的第一个元素的值。

    find() 方法为数组中的每个元素都调用一次函数执行:

    • 当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数。(找到就停止)
    • 如果没有符合条件的元素返回 undefined

    注意: find() 对于空数组,函数是不会执行的。

    注意: find() 并没有改变数组的原始值。

    语法:array.find(function(currentValue, index, arr),thisValue)

    返回值:返回符合测试条件的第一个数组元素值,如果没有符合条件的则返回 undefined

  2. findIndex() 方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置。

    findIndex() 方法为数组中的每个元素都调用一次函数执行:

    • 当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置,之后的值不会再调用执行函数。
    • 如果没有符合条件的元素返回 -1

    注意: findIndex() 对于空数组,函数是不会执行的。

    注意: findIndex() 并没有改变数组的原始值。

    语法:array.findIndex(function(currentValue, index, arr), thisValue)

    返回值:返回符合测试条件的第一个数组元素索引,如果没有符合条件的则返回 -1。

const list = [
    { name: '头部导航', id: 1 },
    { name: '轮播', id: 2 },
    { name: '页脚', id: 3 },
];
const result = list.find(item => item.id === 3);
// result: { name: '页脚', id: 3 }
const index = list.findIndex(item => item.id === 3);
// index: 2

小结

  • 二者都是用来查找数组元素。
  • find 方法返回数组中满足 callback 函数的第一个元素的值。如果不存在返回 undefined。
  • findIndex 它返回数组中找到的元素的索引,而不是其值,如果不存在返回 -1。

reduce、reduceRight

reduce 方法接收两个参数,第一个参数是回调函数(callback)【必须】 ,第二个参数是初始值(initialValue)【可选】。

reduceRight 方法除了与 reduce 执行方向相反外(从右往左),其他完全与其一致。

array.reduce(function(total, current, currentIndex, sourceArray), initialValue)

回调函数接收四个参数:

  • total:MDN 上解释为累计器,可以理解为它应该是截至当前元素,之前所有的数组元素被回调函数处理累计的结果。
  • current:当前被执行的数组元素。
  • currentIndex: 当前被执行的数组元素索引。
  • sourceArray:原数组,也就是调用 reduce 方法的数组。

initialValue 可选。传递给函数的初始值

如果不传入初始值,reduce 方法会从索引 1 开始执行回调函数,如果传入初始值,将从索引 0 开始、并从初始值的基础上累计执行回调。

返回值: 返回计算结果

注意: reduce() 对于空数组是不会执行回调函数的。

const list  = [
  { name: 'left', width: 20 },
  { name: 'center', width: 70 },
  { name: 'right', width: 10 },
];
const total = list.reduce((currentTotal, item) => {
  return currentTotal + item.width;
}, 0);
// total: 100

参考文章

JS常用的循环遍历你会几种

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值