这几天有大神推荐读underscore源码,趁着项目测试的空白时间,看了一下。

  整个underscore包括了常用的工具函数,下面以1.3.3源码为例分析一下。

_.size = function(obj) {
return _.isArray(obj) ? obj.length : _.keys(obj).length;
};

  整个underscore源码基本上都是以上这种方式写的,所以弄懂上面这段源码,整个underscore的源码就大概清楚了六七成了,剩下的源码用些时间,也就迎刃而解。

  因为上面的函数内有_.keys,可能无法一下子弄清楚,下面这个函数源码更容易入门。

  

  _.isNaN = function(obj) {

        return obj !== obj;

    };

  只需弄明白对象_和函数参数obj这两个具体做了什么即可。

var _ = function(obj) {
return new wrapper(obj);
};

  _定义为一个函数,该函数接受一个名为obj的形参,然后返回一个wrapper类的实例。

  在浏览器环境中,_被定位全局对象window的属性。

var root = this;
root['_'] = _; 

  这样,浏览器全局的_与IIFE中的_都指向了同一个对象,在IIFE中对_的操作,也同样反应在全局环境的_中。

  此时,我们就明白了_的一部分原理了。上面提到的_.isNaN,在构造函数对象_上增加了一个isNaN的属性,该属性是一个函数方法。

  下面,接着研究wrapper

  

var _ = function(obj) {
return new wrapper(obj);
};
var wrapper = function(obj) {
this._wrapped = obj;
};
_.prototype = wrapper.prototype;

  函数_返回wrapper类的一个实例,该实例中属性_wrapped是传给函数_的参数,_与wrapper的原型对象指向相同。将underscore相关的方法添加到wrapper原型, 创建的_对象就具备了underscore的方法。

 引自underscore.js context参数用法

  _.each(list, iteratee, [context]);

  context为上下文,如果传递了context参数,则把iterator绑定到context对象上
  如果要修改iterator的调用对象为context,即函数中this为context,就传递这个参数,否则context为undefined
  下面两个示例,运行看看打印出来的this就明白了

  

var arr = [1, 2, 3];
console.log(this);
var newArr =_.map(arr,function(item){
console.log(this);
return item*3;
});
var arr = [1, 2, 3];
console.log(this);
var newArr =_.map(arr,function(item){
console.log(this);
return item*3;
},arr);

underscore源码阅读记录的更多相关文章

  1. underscore源码阅读记录(二)

    引自underscore.js context参数用法 _.each(list, iteratee, [context]); context为上下文,如果传递了context参数,则把iterator ...

  2. EventBus源码解析 源码阅读记录

    EventBus源码阅读记录 repo地址: greenrobot/EventBus EventBus的构造 双重加锁的单例. static volatile EventBus defaultInst ...

  3. Underscore源码阅读极简版入门

    看了网上的一些资料,发现大家都写得太复杂,让新手难以入门.于是写了这个极简版的Underscore源码阅读. 源码: https://github.com/hanzichi/underscore-an ...

  4. underscore源码阅读

    1:函数式编程初探 2:if(obj.length === +obj.length)的判断 3:JS对象属性用中括号表示的优点在于可以用变量表示属性 4:callee,caller---JS高级程序设 ...

  5. flutter_boot android和flutter源码阅读记录

    版本号0.1.54 看源码之前,我先去看下官方文档,对于其源码的设计说明,文中所说的原生都是指android 看完官方文档的说明,我有以下几个疑问 第一个:容器是怎么设计的? 第二个:native和f ...

  6. Vue2.x 响应式部分源码阅读记录

    之前也用了一段时间Vue,对其用法也较为熟练了,但是对各种用法和各种api使用都是只知其然而不知其所以然.最近利用空闲时间尝试的去看看Vue的源码,以便更了解其具体原理实现,跟着学习学习. Proxy ...

  7. ReactiveCocoa 源码阅读记录。

    1:RACSingle 需要订阅信号 RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACS ...

  8. Linux内核源码阅读记录一之分析存储在不同段中的函数调用过程

    在写驱动的过程中,对于入口函数与出口函数我们会用一句话来修饰他们:module_init与module_exit,那会什么经过修饰后,内核就能狗调用我们编写的入口函数与出口函数呢?下面就来分析内核调用 ...

  9. JQuery源码阅读记录

    新建html文件,在浏览器中打开文件,在控制台输入consoole.log(window);新建html文件,引入JQuery后在浏览器中打开,在控制台同样输入consoole.log(window) ...

随机推荐

  1. Kiwi iOS驱动测试开发

    Kiwi是iOS开发一个行为驱动开发库.目标是提供一个BDD库,精美的简单安装和使用. 安装 使用CocoaPods安装: pod 'Kiwi'如果使用Xcode5则使用: pod 'Kiwi/XCT ...

  2. Java变量自增和自减运算符的用法

    1.后加加(num++): 先输出运算结果再加加: public static void main(String[] args){ int num=10; int  p1=num++; System. ...

  3. babel 配置探究及错误解析

    前面的文章说到了react 15的一些特性,众所周知react搭配es6或者叫es2015的开发模式更加的方便快捷.不过提到es2015这个毕竟没有被浏览器广泛支持的规范,要想能够快快乐乐的应用起来, ...

  4. 使用KeepAlived搭建MySQL高可用环境

    使用KeepAlived搭建MySQL的高可用环境.首先搭建MySQL的主从复制在Master开启binlog,创建复制帐号,然后在Slave输入命令   2016年7月25日   配置安装技巧:   ...

  5. C# Exception 写入文件

    /// <summary> /// 将异常打印到LOG文件 /// </summary> /// <param name="ex">异常< ...

  6. 原声JavaScript实现滚动条·改1

    修正了获取元素相对视口左距离的逻辑问题(之前的函数实际获取的是相对于页面左距离).去除了调试时忘记删除的mouseleave事件.将创建滚动条的功能单独列为一个函数. 添加了鼠标点在滚动条什么位置,就 ...

  7. [UCSD白板题] Least Common Multiple

    Problem Introduction The least common multiple of two positive integers \(a\) and \(b\) is the least ...

  8. iOS-详细解读Const

    在过去开发中,几乎每一个人都会定义宏,因为这东西实在是好用,省去了代码量而且还不容易错,而我这篇文中所介绍的const可以完美替带宏定义. 并且苹果也建议大家抛弃宏定义而转投const ,并且swif ...

  9. Excel里内嵌在线翻译

    本来寻思着继续写点系统运行日志跟踪技术的,但早晨哥家领导从单位打来电话,让帮助她的闺蜜搞一个excel翻译的问题,总部IT搞不定.我过去是用excel做了几年工作,却都是些数学计算,跟翻译也扯不上啊: ...

  10. <Oracle Database>诊断文件

    诊断文件 诊断文件是获取有关数据库活动的信息的一种方式,用于解决数据库出现的一些问题,主要包含有关数据库中出现的重要事件的一些信息,这些文件能更好的对数据库进行日常的管 理,主要类型有一下几种: 警告 ...