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. 数组问题:a与&a有的区别

    int a[5] = {0,1,2,3,4};这种用法还是比较常见的. #include <stdio.h> int main(void) { int a[5] = {0,1,2,3,4} ...

  2. Hibernate框架学习1

    框架是什么 1.框架是用来提高开发效率的 2.封装了好了一些功能.我们需要使用这些功能时,调用即可.不需要再手动实现. 3.所以框架可以理解成是一个半成品的项目.只要懂得如何驾驭这些功能即可. orm ...

  3. java 读写Parquet格式的数据 Parquet example

    import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOExce ...

  4. Amoeba读写分离(MySQL)

    实验操作环境: centos服务器  三台机器 role: 192.168.189.129  master-主 192.168.189.130  master-从 192.168.189.131    ...

  5. [RN] React Native 获取验证码 按钮

    React Native 获取验证码 按钮 效果如图: 实现方法: 一.获取验证码 按钮组件 封装 CountDownButton.js "use strict"; import ...

  6. 洛谷 P3373 【模板】线段树 2 题解

    P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入格式 第一行包含三个整数 ...

  7. Python知识点复习

    一.列表1.创建一个文件birthday.py,假设你要祝某人生日快乐!首先将年龄存储在变量age中,将姓名存储在变量name中,让程序输出类似“阿明,23岁生日快乐!” 例如:假设你要祝某人生日快乐 ...

  8. 不了解这12个语法糖,别说你会Java!

    阅读本文大概需要 10 分钟. 作者:Hollis 本文从 Java 编译原理角度,深入字节码及 class 文件,抽丝剥茧,了解 Java 中的语法糖原理及用法,帮助大家在学会如何使用 Java 语 ...

  9. Spring Security教程(二)

    上一篇博客中,Spring Security教程(一),我把用户信息和权限信息放到了xml文件中,这是为了演示如何使用最小的配置就可以使用Spring Security,而实际开发中,用户信息和权限信 ...

  10. [Gamma] 项目展示

    [Gamma] 项目展示 一.工程展示 1.项目简介 定位分析 我们的目标是做一个创意分享网站,在之前的阶段中完成了大框架的搭建,并以此为基础进行界面优化与功能扩展. 典型用户 用户 面临困境 需求功 ...