Array.forEach的那些小秘密


在写地图的聚合功能里,单个聚合点下

  • 包含一个故障点,则聚合圈为红色;
  • 不包含故障点但含离线点,则聚合圈为黄色
  • 不包含故障点和离线点,则聚合圈为绿色

因为地图不包含属性的过滤,只能我们去循环了。但是地图点位包含几万个,每个点位用去循环,跳出,效果很差。
师傅: 你要做优化,你写 forEach ,break跳不出来
我:😶 ??? forEach 跳不出来?
迅速找找度娘,扒forEach的那些小秘密

forEach

forEach 的基础了解

  1. 句法
forEach((element, index, array) => { ... } )

forEach 本质上接收的是一个匿名函数,无法像语句一样,使用 break 进行跳转。看到这里,小伙伴们不禁说, return return~ 那我们就来试一试吧

const arr = [1, 2, 3, 4]
    arr.forEach(n => {
       if(n === 2) {
       	  return false
       }
       console.log(n)
    })

输出为134 ,跳出当次的循环了,小伙伴,好厉害!!那么问题来了

【问】 那我们如何让他 停止接下来的循环?毕竟布噜的开题的优化是要跳过接下来的循环

如何停止循环

  1. 抛出异常,跳出循环
let k = null
const arr = [1, 2, 3, 4]

try {
  arr.forEach(n => {
    if (n === 2) {
      throw Error()
    }
     k = n
  })
} catch (e) {}
console.log(k)

最终输出为 1
2. forEach()除了抛出异常之外,没有其他方法可以停止或中断循环。如果您需要这种行为,那么该forEach()方法就是错误的工具。那我们有什么替换方案呢?

插一嘴🧐 ,从这里也能看出,forEach的本质是 对数组的每个元素进行一次函数内的操作

替换方案

  • 一个简单的for循环
var i = 0;

for (;;) {
  if (i > 3) break; // here 退出循环
  console.log(i);
  i++;
}
  • 一对for...offor...in循环
  • Array.prototype.every()
const isBelowThreshold = (currentValue) => currentValue < 40;

const array1 = [1, 30, 39, 29, 10, 13];

console.log(array1.every(isBelowThreshold));
  • Array.prototype.some()
  • Array.prototype.find()
  • Array.prototype.findIndex()
  • 数组方法:every()some()find()findIndex()使用返回真值的谓词测试数组元素以确定是否需要进一步迭代。

大数据下,为什么forEach 会比for 循环慢得多

这个还与 ES中的实现有关

if (!Array.prototype.forEach) {
  Array.prototype.forEach = function(callback, thisArg) {
    var T, k;
    if (this == null) {
      throw new TypeError(' this is null or not defined');
    }
    
    var O = Object(this);
    var len = O.length >>> 0;
    if (typeof callback !== "function") {
      throw new TypeError(callback + ' is not a function');
    }
    if (arguments.length > 1) {
      T = thisArg;
    }
    
    k = 0;
    while (k < len) {
      var kValue;
      if (k in O) {
        kValue = O[k];
        callback.call(T, kValue, k, O);
      }
      k++;
    }
  };
}

  1. forEach 在实现中对调用者本身进行了一系列的检查,不如 for 循环简单
  2. callback.call(T, kValue, k, O); 在一定程度上也会消耗性能

好奇的小伙伴,可以使用console.profileconsole.profileEnd进行性能测试

【tip】在进行数组较大 for 循环的时候,可以将长度另外提取出来,避免重复获取数组长度

推荐链接

MDN Array.forEach

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值