zoukankan      html  css  js  c++  java
  • for,for-each,for-in,for-of,map的比较

    参考:

    全面解析JavaScript里的循环方法之forEach,for-in,for-of

    Iterator 和 for...of 循环

    JavaScript Array 对象

    常规for

    for循环较为灵活,因为起始索引、条件可以都可以自定义。

    缺点是书写较麻烦,获取数组长度来循环。

            let arr = [];
            for(let i=0;i<10000000;i++){
                arr[i] = i;
            }
    
            let startTime = egret.getTimer();
            let sum:number = 0;
            for(let i=0;i<10000000;i++){
                sum += arr[i];
            }
            console.log(sum);
            console.log(egret.getTimer() - startTime);  //240ms - 380ms
    

    for循环还能多条件判断

    for(let i=0,j<10;i<10&&j<20;i++,j++){
    
    }

    for-each

    foeach适用于遍历数组,减少了获取数组长度的麻烦。

    缺点不能中途跳出循环,不够灵活。

            let arr = [];
            for(let i=0;i<10000000;i++){
                arr[i] = i;
            }
    
            let startTime = egret.getTimer();
            let sum:number= 0;
            arr.forEach((value, index)=>{
                sum += value;
            });
            console.log(sum);
            console.log(egret.getTimer() - startTime);  //300ms-440ms
    

    foreach还有两个参数,arr是数组元素本身,this是传递this关键字

            let arr = [1,2,3];
            arr.forEach((value,index,arr)=>{
                console.log(arr);
                console.log(this);  
            }, this)
    

    forEach循环无法跳出,无法使用break。

    如下所示,尝试break,提示报错;尝试return跳出循环,但是输出值仍然是2,5。

            let arr = [1,2,3,4];
            arr.forEach((value,index)=>{
                //尝试打断循环,仅仅能跳过value=1这一次循环而已,不能跳出forEach整个循环
                if(value == 1){
                    return;
                }
                //尝试修改数组,可以修改
                arr[2] = 5;
    
                //尝试对数组进行删除操作,可以删除
                arr.splice(3,1);
    
                console.log(value);  //2,5
            })
    
            console.log(arr);  // [1,2,5]

    for-in

    从效率来看基本放弃常规数组操作了。

    主要用于遍历object

            let arr = [];
            for(let i=0;i<10000000;i++){
                arr[i] = i;
            }
    
            let startTime = egret.getTimer();
            let sum:number= 0;
            for(let key in arr){
                sum += arr[key];
            }
            console.log(sum);
            console.log(egret.getTimer() - startTime);  //1600ms - 2000ms
    

    遍历object

            let obj = {"name":"peter", "age":23};
            for(let key in obj){
                console.log(key, obj[key]);  //name peter,  age 23
            }
    

    那么这个遍历是顺序的吗?不是顺序的     具体参考:js能够保证object属性的输出顺序吗

    for-of

    for-of是新特性,和for-in的区别是,for-of是获取键值,for-in是获取键名。

            let arr = [];
            for(let i=0;i<10000000;i++){
                arr[i] = i;
            }
    
            let startTime = egret.getTimer();
            let sum:number= 0;
            for(let value of arr){
                sum += value;
            }
            console.log(sum);
            console.log(egret.getTimer() - startTime);  //250ms - 380ms
    

    for-of中可以修改数组,也可以跳出循环。

    for-of获取的键值,for-in获取的是键名。

    for-of不能遍历object,for-in可以。

            let arr = [1,2,3,4];
            for(let value of arr){
                //尝试修改数组,可以修改
                arr[1] = 5;
    
                //尝试删除数组值3,但是不知道值3的索引是多少...
                if(value == 3){
                    //arr.splice(i,3);
                }
    
                //尝试跳出循环,可以跳出
                if(value == 3){
                    break;
                }
                
    
                console.log(value);  //1,5
            }
            console.log(arr); //[1,5,3,4]
    

    因为for-of不能获取索引,在es6中进行了扩展,参考:数组的扩展

            let arr:Array<number> = [1,2,3,4];
            for(let key of arr.keys()){   //报错,Egret中还不能用哎,新特性,只能ES6
                console.log(key);
            }
    

    for-of中使用splice

    let list = [1,2,3,4,5];
    for(let value of list){
        if(value == 2){
            let index = list.indexOf(value);
            if(index != -1){
                list.splice(index,1);
            }
        }else{
            console.log(value);  //1,4,5
        } 
    }

    在删除2以后,数组变成了[1,3,4,5] ,原本访问[1,2,3,4,5]中的3的索引位置,变成了4。 所以输出是1,4,5。

    假如数组中的不是12345,而是5个需要操作的对象,那么3这个对象就被跳过了操作。

    所在在有移除操作的遍历中,不能使用for-of,而是要使用逆循环。

    let list = [1,2,3,4,5];
    let len = list.length;
    for(let i=len-1;i>=0;i--){
        if(list[i]==2){
            let index = list.indexOf(2);
            list.splice(index,1);
        }else{
            console.log(list[i]);  //5,4,3,1
        }
    }

    这样3这个位置的对象,也会被进行输出操作,而不是被跳过。

     map

    JS的forEach和map方法的区别

     map()方法创建一个新数组,其结果是在调用数组中的每个元素上调用一个提供的函数

    var numbers = [1, 5, 10, 15];
    var doubles = numbers.map(function(x) {
       return x * 2;
    });
    // doubles is now [2, 10, 20, 30]
    // numbers is still [1, 5, 10, 15]
    
    var numbers = [1, 4, 9];
    var roots = numbers.map(Math.sqrt);
    // roots is now [1, 2, 3]
    // numbers is still [1, 4, 9]
    

      

      

  • 相关阅读:
    第四部分 | 第19章 —— Cocos2d-HTML5
    第四部分 | 第18章 —— 可视化开发
    第四部分 | 第17章 —— 多平台下的Cocos2d
    第三部分 | 第16章 —— 并发编程
    第三部分 | 第15章 —— 缓存与池
    第三部分 | 第14章 —— 网络
    第三部分 | 第13章 —— 数据持久化
    第二部分 | 第12章 —— 物理引擎
    ASA failover配置(A/S)
    深信服AF ipsec ikev2 新版本尝鲜(对接Azure)
  • 原文地址:https://www.cnblogs.com/gamedaybyday/p/9413003.html
Copyright © 2011-2022 走看看