下划线_.each和_.map之间的真正区别是什么

What is really the difference between underscore _.each and _.map?

本文关键字:是什么 区别 之间 each map 下划线      更新时间:2023-09-26

我正在使用UndercoreJs。考虑这个代码:

var docs = [
    {name : 'Anders', niche : 'Web Development'}, 
    {name : 'Johnny', niche : 'Design'}, 
    {name : 'Eric', niche : 'PhotoShop'}
];
var newDocs = _.map(docs, function (doc){
    delete doc.niche;
    return doc;
});

我在这里使用.each还是.map并不重要。结果完全一样。

在上述情况下,两者之间的真正区别是什么?

map旨在成为一个函数映射方法:它的函数参数应该返回一个值,但预计不会有任何副作用

each只是命令式for循环的函数替换:它的目的是产生效果,并且它不应该返回任何值

例如,这将是map:更合适的用途

var docs = getDocs();
var docTitles = _.map(docs, function (doc){
    return doc.title;
});
// expect `docs` to be unchanged

而这将是each:的适当用途

var docs = getDocs();
_.each(docs, function (doc){
    delete doc.niche;
});
// expect `docs` to be altered.

_.each(list,iteratee)

对元素列表进行迭代,依次生成一个迭代函数。

每次调用iteratee都使用三个参数:(element、index、list)。如果list是一个JavaScript对象,iteratee的参数将是(value、key、list)。返回用于链接的列表

_.each({one: 1, two: 2, three: 3}, alert);
=> alerts each number value in turn...

_.map(列表,iteratee)

通过转换函数(iteratee)映射列表中的每个值,生成一个新的值数组。

如果list是一个JavaScript对象,iteratee的参数将是(value,key,list)

_.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; });
=> [3, 6, 9]

请参阅文档

您关于结果"完全相同"的断言是不真实的。_.each()函数返回原始列表,但_.map()返回名单。您在执行过程中直接修改原始对象,因此最终会在每个列表中引用相同的对象,但使用_.map(),最终会得到两个独立的数组实例。

您只需查看源代码即可看出区别:

  • _.each:

    _.each = _.forEach = function(obj, iteratee, context) {
        if (obj == null) return obj;
        iteratee = createCallback(iteratee, context);
        var i, length = obj.length;
        if (length === +length) {
          for (i = 0; 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:

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