map()是underscore.js中一个处理数组和对象的方法。

params:

1. array || obj

2. callback

3. content 上下文指向

使用:
  var obj = {a:1, b: 2, c: 3}
var arr = [1.3,5,6,76]
_.map(arr, function(value, index, obj){
return value*3
});

这个代码如果我自己写的话当然很简单的想法了,就是判断传入参数类型,进行遍历,然后判断是否有回调,有的话,就执行,并将结果返回出去,没有的话,就将原值返回出去。

下面看下源码是怎样的吧。

调用过程:
  1. map():

     _.map = function (obj, iteratee, context) {
    iteratee = cb(iteratee, context);
    var keys = !isArray(obj) && Object.keys(obj);
    var length = (keys || obj).length;
    var result = Array(length);
    for(var index = 0; index < length; index++) {
    var current = keys ? keys[index] : index;
    result[index] = iteartee(obj[current], index, obj);
    }
    } map方法在一开始调用了一个cb方法,对iteratee进行重写,下面看下cb
  2. cb()

     var defaultCb = function(value) {
    return value;
    }
    /**
    * argcount 在生成迭代的时候,对迭代器有几个参数的要求,默认3
    * */
    var cb = function(value, context, argcount) {
    if (value == null ) return defaultCb;
    if (isFunc(value)) return optimizeCb(value, context, argCount);
    ...
    } 这里其实没什么好说的,如果没有回调,就给他一个默认方法。重点应该是在optimizeCb方法上。
  3. optimizeCb()

     var optimizeCb = function(func, context, argCount) {
    if (context == void 0 ) return func;
    switch (argCount == null ? 3 : argCount) {
    case 1: return function(value) {
    return func.call(context, value)
    }
    ...
    case 3: return function(value, index, object) {
    return func.call(context, value, index, object);
    }
    }
    } 在optimizeCb中,会注意到underscore使用了void 0 来代替undefined进行判断。
    void是js的一个函数,但是,似乎很少用到,由于void的返回值是undefined,于是,被代替undefined以用来判断,毕竟,相比undefined,可以改写这一点,void更可靠一点
    可以看到,在optimizeCb中使用了call函数,对func重新绑定了上下文,并返回。

其实在map方法中,主要的是iteratee设计(迭代设计),迭代可以基本大家都知道,但是却不十分了解。

迭代: 简单的说:就是通过某一种方法对数组,对象以及类数组中的每个元素进行处理。

而一个迭代器,至少有两个基础部分:

  1. 被迭代集合
  2. 当前迭代过程

    而map中的迭代过程则是一个函数,就是传入的处理函数。至于cb函数,则是根据传参的不同情况创建迭代过程,为每次的迭代服务。

    optimizeCb函数是对迭代函数的一个优化,基本上,map方法是通过迭代,对数据进行操作,从而返回一个新数组

underscore_1: map()的更多相关文章

  1. mapreduce中一个map多个输入路径

    package duogemap; import java.io.IOException; import java.util.ArrayList; import java.util.List; imp ...

  2. .NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法

    .NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法 0x00 为什么需要Map(MapWhen)扩展 如果业务逻辑比较简单的话,一条主管道就够了,确实用不到 ...

  3. Java基础Map接口+Collections工具类

    1.Map中我们主要讲两个接口 HashMap  与   LinkedHashMap (1)其中LinkedHashMap是有序的  怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...

  4. Java基础Map接口+Collections

    1.Map中我们主要讲两个接口 HashMap  与   LinkedHashMap (1)其中LinkedHashMap是有序的  怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...

  5. 多用多学之Java中的Set,List,Map

            很长时间以来一直代码中用的比较多的数据列表主要是List,而且都是ArrayList,感觉有这个玩意就够了.ArrayList是用于实现动态数组的包装工具类,这样写代码的时候就可以拉进 ...

  6. Java版本:识别Json字符串并分隔成Map集合

    前言: 最近又看了点Java的知识,于是想着把CYQ.Data V5迁移到Java版本. 过程发现坑很多,理论上看大部分很相似,实践上代码写起来发现大部分都要重新思考方案. 遇到的C#转Java的一些 ...

  7. MapReduce剖析笔记之八: Map输出数据的处理类MapOutputBuffer分析

    在上一节我们分析了Child子进程启动,处理Map.Reduce任务的主要过程,但对于一些细节没有分析,这一节主要对MapOutputBuffer这个关键类进行分析. MapOutputBuffer顾 ...

  8. MapReduce剖析笔记之七:Child子进程处理Map和Reduce任务的主要流程

    在上一节我们分析了TaskTracker如何对JobTracker分配过来的任务进行初始化,并创建各类JVM启动所需的信息,最终创建JVM的整个过程,本节我们继续来看,JVM启动后,执行的是Child ...

  9. MapReduce剖析笔记之五:Map与Reduce任务分配过程

    在上一节分析了TaskTracker和JobTracker之间通过周期的心跳消息获取任务分配结果的过程.中间留了一个问题,就是任务到底是怎么分配的.任务的分配自然是由JobTracker做出来的,具体 ...

随机推荐

  1. Spring Cloud微服务安全实战_2-1_开发环境

    开发环境: JDK  :1.8 IDE : idea  数据库:mysql 5.6.5 框架:springboot,mybatisplus PGA:(后边用到再安装) Promethus (普罗米修斯 ...

  2. SDOI2010选做

    Round1 D1T1外星千足虫 \(BSOJ2793\)--高斯消元解异或方程组 简述 有\(n\)个数\(\{a_i\}\) 给出\(m\)个信息,每个信息给出\(\displaystyle{(\ ...

  3. linux学习18 shell脚本基础-bash变量和逻辑运行

    一.回顾 1.用户管理,权限管理,install,mktemp 2.用户管理: 3.权限管理: mode,ownership mode: user group other r w x 4.命令:ins ...

  4. java 构造实例

    Person父类 package com.oracle.demo03; public class Person { private String name; private int age; //需要 ...

  5. 2017年计算语义相似度最新论文,击败了siamese lstm,非监督学习

    Page 1Published as a conference paper at ICLR 2017AS IMPLE BUT T OUGH - TO -B EAT B ASELINE FOR S EN ...

  6. java 中 public default protected private 的区别

    对于继承自己的class,父类可以认为他们都是自己的子女,而对于和自己都在同一个目录下的class,可以认为都是自己的朋友. public:对所有用户开发,所有用户都可以直接调用 private:自己 ...

  7. Java 并发系列之四:java 多线程

    1. 线程简介 2. 启动和终止线程 3. 对象及变量的并发访问 4. 线程间通信 5. 线程池技术 6. Timer定时器 7. 单例模式 8. SimpleDateFormat 9. txt ja ...

  8. Java集合详解4:一文读懂HashMap和HashTable的区别以及常见面试题

    <Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...

  9. [Gamma]Scrum Meeting#9

    github 本次会议项目由PM召开,时间为6月4日晚上10点30分 时长15分钟 任务表格 人员 昨日工作 下一步工作 木鬼 撰写博客,组织例会 撰写博客,组织例会 swoip 前端显示屏幕,翻译坐 ...

  10. Windows Server实例防火墙策略的配置方法

    概述 本文介绍在Windows Server实例中,如何配置防火墙策略的方法. 详细描述 配置Windows Server版本的防火墙功能方法,参考如下步骤. 提示:此处以Windows Server ...