for , foreach , map ,for...in , for...of 五种循环方法的使用及性能对比

138 阅读3分钟

一、for , foreach , map ,for...in , for...of 五种循环方法的使用

1、for循环的使用

(1)、遍历数组:

let arr = [1,2,3,4,5];
for(let i=0;i<arr.length;i++){
    console.log(arr[i])//输出:1 2 3 4 5
}

(2)、遍历对象:

let obj = {
    name:'wang',
    age:24,
}
let objKey = Object.keys(obj)
for(let i = 0,  i < objKey.length;i++){ 
    console.log(profile[objKey[i]]) // 输出:'wang' 24
}

(3)、遍历字符串:

let str = "abcd"; 
for(let i = 0;i < str.length ;i++){    
    console.log(str[i]) // 输出:a b c d
}

2、forEach循环的使用

(1)、遍历数组:

let arr = [1,2,3,4,5];
arr.forEach(i => console.log(arr[i]) //输出:1 2 3 4 5

(2)、遍历对象:

let obj = {
    name:'wang',
    age:24
}
let objKey = Object.key(obj);
objKey.forEach(i=>{
    console.log(obj[i])//输出:'wang' 24
})

3、map循环的使用

创建一个新数组,新数组的结果是在原数组的基础上每一个元素做相应函数操作。

let arr = [1,2,3,4,5];
let res = arr.map(i => i * i);
console.log(res);//输出:[1,4,9,16,25]

4、for……in 循环的使用

(1)、遍历数组:

let arr = [1,2,3,4]; 
for(let i in arr) {     
    console.log(arr[i]) // 输出:1 2 3 4  
}

(2)、遍历对象:

let obj = {
    name:'wang',
    age:24
}
for(let i in obj) {     
    console.log(obj[i]) // 输出:'wang' 24 
}

(3)、遍历字符串:

let str = "abcd";
for(let i in str){     
    console.log(str[i]); // 输出:a b c d   
}

5、for……of 循环的使用

(1)、遍历数组:

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

(2)、遍历字符串:

let str = "abcd"; 
for (let item of str) {     
    console.log(item); // 输出:a b c d
}

二、性能对比

1、我使用的是leetCode上的第121题这个暧昧的题目做的验证:

题目:给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

示例 1:

输入:[7,1,5,3,6,4]

输出:5

解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。

注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

示例 2:

输入:prices = [7,6,4,3,1]

输出:0

解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

2、使用的是相同的解题方法:

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function(prices) {
   let max = 0;
   let minNumber = prices[0];
//    1、for循环---(76ms,50.4MB)---(72ms,50.6MB)---(88MS,50.6MS)----(88MS,50.7MB)---(80MS,50.7MB)
        for (let i = 0; i < prices.length; i++) {
           if(prices[i]<minNumber){
               minNumber = prices[i];
           }else{
               if(prices[i]-minNumber>max){
                  max = prices[i]-minNumber;
               } 
           }
        }
// 2、forEach循环-----(80ms,50.6MB)---(72ms,50.6MB)---(96ms,50.7MB)---(96ms,50.5MB)-
--(104ms,50.6MB)---(76ms,50.5MB)
        // prices.forEach(item=>{
        //     if(item<minNumber){
        //         minNumber=item
        //     }else {
        //         if(item-minNumber>max){
        //             max=item-minNumber
        //         }
        //     }
        // })
// 3、for……in循环----(144ms,79.6MB)----(152ms,79.7MB)---(136ms,79.9MB)---(160ms,79.9MB)---(148ms,79.7MB)
    //    for(let i in prices){
    //        if(prices[i]<minNumber){
    //            minNumber = prices[i]
    //        }else {
    //            if(prices[i]-minNumber>max){
    //                max = prices[i]-minNumber
    //            }
    //        }
    //    }
// 4、for……of循环的使用----(88ms,50.BMB)--(80ms,51MB)---(88ms,51.1MB)---(88ms,50.9MB)--(88ms,50.8MB)
        // for(let item of prices){
        //     if(item<minNumber){
        //         minNumber = item;
        //     }else {
        //         if(item-minNumber>max){
        //             max = item-minNumber
        //         }
        //     }
        // }
        return max;
};

复杂度分析

  • 时间复杂度:O(n)O(n),只需要遍历一次。
  • 空间复杂度:O(1)O(1),只使用了常数个变量。

3、总结

1、性能方面对比:

for > for……of > forEach > for……in

2、建议:

(1)开发过程中尽量避免使用for……in这种遍历方式,他会拖累整体性能;

(2)for的话由于可能公司有语义化规定的不让使用,但是如果是封装公共类方法或者底层的东西,建议使用for来做循环;

(3)大致的推荐:遍历数组和字符串可以使用for……of来做,遍历对象可以使用forEach来做,具体根据需求来定,尽量考虑到每个方面,找到一个最优解。