javascript - 为什么 underscore 的 _.each 与 _.map 不同?

查看:130
本文介绍了javascript - 为什么 underscore 的 _.each 与 _.map 不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

刚开始看 underscore 的源码,看到 _.each 与 _.map 的实现,这两个函数的区别是是否返回一个对传入的类数组的每个元素进行操作并将结果保持在新数组中返回。

在 underscore 中的 _.each 与 _.map:

_.each = _.forEach = function(obj, iteratee, context) {
    iteratee = optimizeCb(iteratee, context);
    var i, length;
    if (isArrayLike(obj)) {
      for (i = 0, length = obj.length; i < length; i++) {
        iteratee(obj[i], i, obj);
      }
    } else {
      var keys = _.keys(obj);
      for (i = 0, length = keys.length; i < length; i++) {
        iteratee(obj[keys[i]], keys[i], obj);
      }
    }
    return obj;
  };

_.map = _.collect = function(obj, iteratee, context) {
    iteratee = cb(iteratee, context);
    var keys = !isArrayLike(obj) && _.keys(obj),
        length = (keys || obj).length,
        results = Array(length);
    for (var index = 0; index < length; index++) {
      var currentKey = keys ? keys[index] : index;
      results[index] = iteratee(obj[currentKey], currentKey, obj);
    }
    return results;
  };

为什么在 _.each 不与 _.map 中相同的使用:

for (var index = 0; index < length; index++) {
      var currentKey = keys ? keys[index] : index;
      results[index] = iteratee(obj[currentKey], currentKey, obj);
    }

而是使用 if...else... 结构?

为什么不这样写?

_.each = function(obj, iteratee, context) {
    iteratee = cb(iteratee, context);
    var keys = !isArrayLike(obj) && _.keys(obj),
        length = (keys || obj).length;
        
    for (var index = 0; index < length; index++) {
      var currentKey = keys ? keys[index] : index;
      iteratee(obj[currentKey], currentKey, obj);
    }
  };

是因为传入 _.each 中的类数组频率高于传入对象吗?

解决方案

个人理解

两个函数的核心区别是 是否返回结果。
代码中的核心区别 就体现在在了 results上。
出于性能考虑 , 创建定长的数组 比 想数组中逐个追加元素的 速度快。
历次类推 results _> len _> keys
既然keys已经可知了, 统一一个循环处理keys数组就可以了。 至于每次三目运算符的性能损耗忽略不计吧, 很低很低。

这篇关于javascript - 为什么 underscore 的 _.each 与 _.map 不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆