95、常用的10种js数组遍历方式

1. for循环 

    let arr=[1,2,3,4];

    for(let i=0;i<arr.length;i++){
        console.log(arr[i]);
    }

  

2. for...in(适用于对象)

缺点:

  • 用for-in不仅数组本身的元素将被遍历到,那些由用户添加的附加元素也将被遍历到。例如某数组有这样一个属性 myArray.name,那么在某次循环中将会出现 index=”name” 的情况。
  • 数组原型链上的属性也可能被遍历到。
  • 在某些情况下,将会以任意顺序去遍历数组元素。

目的:用于遍历包含键值对(key-value对)的对象对数组并不是那么友好。
 

    一、遍历数组
    let arr=[1,2,3,4];
    arr["name"] = "cc"
    
    for(key in arr){
        console.log("下标"+key+"的值:"+arr[key]);
    }

 

二、遍历对象

    var person = {
        name: "bty",
        age: 21,
        sex: "man"
    };
    for (key in person) {
        console.log("属性:" + key + ",值:" + person[key]);
    }

 

 

3. for...of (适用于数组)

  • for-of是ES6引进的新的循环遍历语法。
  • 而for-of 则是专门用来遍历数组中的元素。直接获取数组的值。
  • for-in 是用于遍历对象的属性,对数组并不友好;
    let arr = [1,2,3,"a",true]; 

    for(let value of arr){ //直接获取数组的值
        console.log(value);
    }

 

 

4. forEach

  • 可以获取数组元素和数组下标。第一个参数为数组的元素,第二个元素为数组的下标。
  • 缺点:不能使用 break 语句来跳出循环(报错),也不能使用 return 语句来从闭包函数中返回。
    let arr = [1,2,3,"a",true]; 

    // value为数组元素,index为数组下标
    arr.forEach((value,index) =>{
        console.log("下标"+index+"的值为:"+value)
    })

 

5. map()

  • map方法将数组的所有成员依次传入参数函数,然后把每一次的执行结果组成一个新数组返回。
  • map方法的第一个参数是一个函数,向它传入三个参数:值、下标和数组本身
  • map方法的第二个参数,用来绑定回调函数内部的this变量,即间接操作这个参数。此时函数不能使用箭头函数,否则this会指向window。
  • 注意:是返回一个新数组,而不会改变原数组。
  • 缺点:不能使用 break 语句来跳出循环(报错),也不能使用 return 语句来从闭包函数中返回。
    let arr = [1,2,3]; 

    let newArr = arr.map(item =>{
        return item+1;
    })

    console.log(arr) // 原数组未变:[1,2,3]
    console.log(newArr) //新数组:[2,3,4]

两个参数的map方法:

    let a = ["aa", "bb", "cc"];

    [1, 2].map( function(value, index, arr) { // 注意:绑定this时不能是用箭头函数,不然this会指向window。
        console.log(this[index])    // this就是第二个参数a
    }, a)

    // 打印结果:aa bb

forEach循环和map循环一样也可以绑定回调函数内部的this变量,间接操作其它变量(参考上面的map()循环例子) 

6. filter()过滤

  • 用于过滤数组成员满足条件的成员组成一个新数组返回
  • 第一个参数是一个函数,该函数也可以接受三个参数:值,下标 和整个数组
  • filter方法也可以接受第二个参数,用来绑定参数函数内部的this变量
  • 所有数组成员依次执行该函数(第一个参数),返回结果为true的成员组成一个新数组返回。
  • 该方法不会改变原数组
    let a = [1,2,3,4,5,6,7,8];

    let newArr = a.filter((value,index)=>{ //获取数组a中小于5的所有元素
        return value<5;
    })

    console.log(newArr) //[1,2,3,4]

7. some() 、every() 统计数组是否满足某个条件 

  • 接受一个函数作为参数,所有数组成员依次执行该函数,都返回一个布尔值,表示判断数组成员是否符合某种条件。
  • 该参数函数接受三个参数:值,下标 和整个数组。
  • some方法是只要一个成员的返回值是true,则整个some方法的返回值就是true,否则返回false
  • every方法则相反,所有成员的返回值都是true,整个every方法才返回true,否则返回false
  • 不同之处:some()只要有一个是true,便返回true;而every()全部为true,才返回true

some的使用:

    let a = [1,2,3,4,5,6,7,8];

    let res = a.some((value,index)=>{  //只有8大于7
        return value>7
    })
    
    console.log(res) //true

every的使用:

    let a = [1,2,3,4,5,6,7,8];

    let res = a.every((value,index)=>{ //只有8大于7
        return value>7
    })

    console.log(res) //false

 这两个方法在实际开发中,大有可用之处。比如在判定用户是否勾选了不可操作的数据,或者是否勾选了一条可以操作的数据可以使用这两个方法遍历循环数组。

8. reduce()、reduceRight() 依次处理数组的每个成员

  • 依次处理数组的每个成员,最终累计为一个值
  • 第一个参数是一个函数,函数接受以下四个参数:累积变量、值、下标、原数组,前两个是必须的。每次的返回值会累计到累计变量
  • 第二个参数: 如果要对累积变量指定初值,可以把初值放在第二个参数。
  • 区别reduce是从左到右处理(从第一个成员到最后一个成员),reduceRight则是从右到左(从最后一个成员到第一个成员),其他完全一样。

 利用reduce获取数组中最长的字符串:

nowRes 存放每一轮的结果,value是当前遍历的值,index是当前遍历值的下标。

    let a = ["aaa","cc","fbwss","dw"];

    let res = a.reduce((nowRes,value,index)=>{
        console.log("当前累积变量:"+nowRes+"  当前值:"+value+"  当前下标:"+index);
        return nowRes.length < value.length ? value: nowRes;
    },"") //设置最长字符nowRes的初始值为""

    console.log(res); //fbwss

 

 9、不同遍历方式的对比

一:map(),foreach,filter循环的共同之处:

  1.  foreach,map,filter循环中途是无法停止的,总是会将所有成员遍历完。
  2.  他们都可以接受第二个参数,用来绑定回调函数内部的this变量,将回调函数内部的this对象,指向第二个参数,间接操作这个参数(一般是数组)。

二:map()循环和forEach循环的不同:

  1.  forEach循环没有返回值
  2.  map,filter循环有返回值。

三:map循环和filter()循环都会跳过空位,for和while不会

var f = function (n) { 
    return 'a' 
}; 
 
[1, undefined, 2].map(f) // ["a", "a", "a"] 
[1, null, 2].map(f) // ["a", "a", "a"]
[1, , 2].map(f) // ["a", , "a"]
 

上面代码中,map方法不会跳过undefined和null,但是会跳过空位。forEach方法也会跳过数组的空位,这里就不举例了。

四:some()和every():

  1. some()只要有一个是true,便返回true
  2. 而every()只要有一个是false,便返回false.

五:reduce(),reduceRight():

  1. reduce是从左到右处理(从第一个成员到最后一个成员)
  2. reduceRight则是从右到左(从最后一个成员到第一个成员)。

六:Object对象的两个遍历Object.keys与Object.getOwnPropertyNames:

  1. 他们都是遍历对象的属性,也是接受一个对象作为参数,返回一个数组,包含了该对象自身的所有属性名
  2. Object.keys不能返回不可枚举的属性
  3. Object.getOwnPropertyNames能返回不可枚举的属性

举例:

数组的length属性是不可枚举的属性,所以只出现在Object.getOwnPropertyNames方法的返回结果中。

   let a = ["aaa","cc","fbwss","dw"];

    Object.keys(a) // ["0", "1", "2", "3"]
    Object.getOwnPropertyNames(a)  //["0", "1", "2", "3", "length"]

如果没有不可枚举的属性,可以使用这两个方法:

var obj = {
  p1: 123,
  p2: 456
};
 
Object.keys(obj).length // 2
Object.getOwnPropertyNames(obj).length // 2

更多参考:https://blog.csdn.net/qq_41899174/article/details/82797089

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值