美文网首页
JS数组的几种遍历方法

JS数组的几种遍历方法

作者: 简森w | 来源:发表于2018-04-10 00:03 被阅读0次

    前言

    最近感觉自己对数组遍历的方法有点混乱,for循环、forEach( )、map( )等方法混合使用,没有一个统一的规范,所以就打算总结一下。

    ES5中的数组遍历方法

    ES5为数组定义了5个迭代方法。每个方法都接受两个参数:要在每一项上运行的函数和(可选的)运行该函数的作用域对象——影响 this 的值。
    而传入的函数又可以接受三个参数:当前遍历的数组项的值,该项在数组中的位置和数组对象本身。

    every( )

    对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则every( )返回true。例如:

        let numbers = [1, 2, 3, 4];
        let everyResult = numbers.every((item, index, array)=>{
            return item > 1;
        })
        console.log(everyResult);  // 输出 false
    

    filter( )

    即对数组中的每一项运行给定函数,然后返回该函数会返回true的项。从名字就看得出来,这个方法是用来过滤数组项的,例如:

        let numbers = [1, 2, 3, 4];
        let filterResult = numbers.filter((item, index, array)=>{
            return item > 1;
        })
        console.log(filterResult);  // 输出 [2, 3, 4]
    

    forEach( )

    对数组的每一项运行给定函数。forEach方法是唯一一个没有返回值的,纯粹用来遍历数组。

        let numbers = [1, 2, 3, 4];
        numbers.forEach((item, index, array)=>{
            // 执行某些操作
        })
    

    map( )

    对数组的每一项运行给定函数,返回每次函数调用的返回值组成的数组。map方法就是有返回值的forEach方法,例如:

        let numbers = [1, 2, 3, 4];
        let mapResult = numbers.map((item, index, array)=>{
            return item * 2;
        })
        console.log(mapResult); // 输出 [2, 4, 6, 8]
    

    some( )

    对数组的每一项运行给定函数,如果该函数对任一项返回true,则some( )就返回true。some和every就像 ||&&,some是只要有一项满足,就返回true。

        let numbers = [1, 2, 3, 4];
        let someResult = numbers.some((item, index, array)=>{
            return item > 3;
        })
        console.log(someResult);  // 输出 true
    

    ES5的这几个迭代方法,如果是只对item(当前遍历的数组项)进行操作,是不会改变原数组的,但是也可以通过给定函数中接收的index参数来改变原数组

    除了ES5这几个方法,还有常见的简单for循环和ES6的for...of。

    for...of

    ES6借鉴了Java、Python等语言,引入了for...of循环。for...of主要用来统一ES6多种数据结构的遍历方法,不仅可以遍历数组,还可以遍历MapSet这两种ES6新推出的数据结构。只要具有iterator接口的数据结构,就可以用for...of循环来遍历。还可以遍历某些类似数组的对象,比如arguments对象、DOM NodeList 对象。

    let numbers = [1, 2, 3, 4];
    for(let item of numbers){
        console.log(item);
    }
    //输出
    // 1
    // 2
    // 3
    // 4
    

    有关ES6新特性的内容,可以参考阮一峰老师的ES6入门教程

    不推荐使用for...in来遍历数组,只用来遍历对象的属性

    性能分析

    这里主要测试一下for循环forEachfor...ofmapfor...in这几个方法遍历一个长度为100000的数组所耗费的时间。

    //测试数据: arr = [1,2,3,4,...,99999,100000];
    
    //普通for循环
    console.time('普通for循环');
    for(let i=0; i<arr.length; i++){
    
    }
    console.timeEnd('普通for循环')
    //控制台输出 => 普通for循环: 0.923095703125ms
    
    
    //forEach循环
    console.time('forEach循环');
    arr.forEach((item)=>{
    
    })
    console.timeEnd('forEach循环')
    //控制台输出 => forEach循环: 1.973876953125ms
    
    
    console.time('for...of循环');
    for(let item of arr){
    
    }
    console.timeEnd('for...of循环')
    //控制台输出 => for...of循环: 3.5810546875ms
    
    
    //for...in循环
    console.time('for...in循环');
    for(let item in arr){
        
    }
    console.timeEnd('for...in循环')
    //控制台输出 => for...in循环: 15.35693359375ms
    
    
    //map循环循环
    console.time('map循环');
    arr.map((item) => {
        
    })
    console.timeEnd('map循环')
    //控制台输出 => map循环: 19.4990234375ms
    

    可能由于电脑配置等问题,这里你的控制台输出可能会不一样,甚至你刷新一下浏览器,两次的输出也会不一致。这里map( )居然比for...in的性能还低,印象中是for...in最低的,可能是因为测试的次数太少,有待研究。

    总结

    从性能上来说,for循环 > forEach > for...of > for...in > map,所以一般来说使用for循环是性能最高的,但是写法稍微复杂了点。但是性能好和要使用哪种遍历方法并没有太大关系,以现在的硬件水平来说,这里的性能差异完全可以忽略。所以一般来说,还需要考虑语义和功能需求。

    如果你需要将数组按照给定规则转换并返回该结果数组,就使用map

    如果你需要进行简单的遍历,用 forEach 或者 for of,但是 forEach 不能通过return和break语句来终止循环,所以如果需要中途终止循环,就使用 for...of或者 for循环

    如果是在遍历数组的同时,需要改变原数组中的对应项,就用for循环

    for...in会把数组所拥有可枚举的属性都遍历一次,所以可能会有意想不到的结果,不推荐用来遍历数组。

    另外的三个,every( )filter( )some( )按功能需要来使用即可。

    相关文章

      网友评论

          本文标题:JS数组的几种遍历方法

          本文链接:https://www.haomeiwen.com/subject/vanwhftx.html