概述

很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以就了结研究underscore源码这一心愿吧。

underscore.js源码研究(1)

underscore.js源码研究(2)

underscore.js源码研究(3)

underscore.js源码研究(4)

underscore.js源码研究(5)

underscore.js源码研究(6)

underscore.js源码研究(7)

underscore.js源码研究(8)

参考资料:underscore.js官方注释undersercore 源码分析undersercore 源码分析 segmentfault

解决冲突

我们知道,_既是underscore的函数也是对象,我们把方法先挂载到它的对象属性上,使得方法可以直接调用,然后我们利用mixin方法把这些方法挂载到它的原型属性上,使得这个函数返回的underscore对象可以利用这些方法。

那么如果其它库也用到了_这个符号呢?underscore中是这样解决的:

var previousUnderscore = root._;

_.noConflict = function() {
root._ = previousUnderscore;
return this;
}; //给underscore重新定义一个符号:
var __ = _.noConflict();

内建方法

underscore这个库里面有一些私有的变量和方法,也会暴露出一些方法,这些暴露出的方法一旦被用户改写,可能整个库就不能按照希望的方向运行了。所以underscore把一些暴露的方法赋给一些内建方法,然后在其它方法使用这些方法的时候可以用内建方法判断是否被改写了。示例如下:

//声明内建方法
var builtinIteratee; //双重赋值赋给内建方法
_.iteratee = builtinIteratee = function(value, context) {
return cb(value, context, Infinity);
}; //cb函数中判断iteratee方法是否被改写。
var cb = function(value, context, argCount) {
if (_.iteratee !== builtinIteratee) return _.iteratee(value, context);
if (value == null) return _.identity;
if (_.isFunction(value)) return optimizeCb(value, context, argCount);
if (_.isObject(value) && !_.isArray(value)) return _.matcher(value);
return _.property(value);
};

值得一提的是,由于js中传递的是引用,所以赋给内建方法并不会有太大的内存开销,所以我觉得这个想法非常好。

创建对象

new Person()实际上为我们做了如下事情:

//创建一个对象,并设置其指向的原型
var obj = {'__proto__': Person.prototype}; //调用Person()的构造方法,并且将上下文(this)绑定到obj上
Person.apply(obj, arguments); //返回创建的对象
return obj;

但是使用new需要一个构造函数,这在很多时候非常不方便。更多时候,我们希望通过一个对象直接创建另一个对象,于是就有了Object.create()方法。Object.create(obj)的原理是这样的:

//创建一个临时的构造函数,并将原型指向
var Ctor = function() {};
ctor.prototype = obj; //通过new新建一个对象
var obj2 = new Ctor(); //清除Ctor,防止内存泄漏。并返回obj2
Ctor.prototype = null;
return obj2;

所以,mdn上这样描述Object.create()方法:创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。

需要注意的是,为了提升速度,underscore把Ctor进行了缓存

var Ctor = function() {};

所以后面当我们为了防止内存泄漏清除Ctor的时候,只是清除它的原型。

而underscore的baseCreate方法就是对Object.create()方法的polyfill

var baseCreate = function(prototype) {
if (!_.isObject(prototype)) return {};
//nativeCreate即是Object.create()方法
if (nativeCreate) return nativeCreate(prototype); Ctor.prototype = prototype;
var result = new Ctor;
Ctor.prototype = null; return result;
};

需要注意的是,Object.create()方法支持多个参数,但是underscore的baseCreate方法只支持一个参数

underscore.js源码研究(2)的更多相关文章

  1. underscore.js源码研究(8)

    概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...

  2. underscore.js源码研究(7)

    概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...

  3. underscore.js源码研究(6)

    概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...

  4. underscore.js源码研究(5)

    概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...

  5. underscore.js源码研究(4)

    概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...

  6. underscore.js源码研究(3)

    概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...

  7. underscore.js源码研究(1)

    概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...

  8. underscore.js源码解析(五)—— 完结篇

    最近公司各种上线,所以回家略感疲惫就懒得写了,这次我准备把剩下的所有方法全部分析完,可能篇幅过长...那么废话不多说让我们进入正题. 没看过前几篇的可以猛戳这里: underscore.js源码解析( ...

  9. underscore.js 源码

    underscore.js 源码 underscore]JavaScript 中如何判断两个元素是否 "相同" Why underscore 最近开始看 underscore.js ...

随机推荐

  1. Tarjan 割点,桥

    /* ggg ggg ggggggg ggggggg ggggggggggggggggggg ggggggggggggggg ggggggggggg ggggggg ggg g */ /* gyt L ...

  2. mysql explain中的type列含义和extra列的含义

    很多朋友在用mysql进行调优的时候都肯定会用到explain来看select语句的执行情况,这里简单介绍结果中两个列的含义. 1 type列 官方的说法,说这列表示的是“访问类型”,更通俗一点就是: ...

  3. Django框架之验证码生成示例

    一.生成随机颜色的图片 1)前端代码展示 <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  4. hadoop 修改datanode balance带宽使用限制

    前段时间,一个客户现场的Hadoop看起来很不正常,有的机器的存储占用达到95%,有的机器只有40%左右,刚好前任的负责人走了,这边还没有明确接班人的时候. 我负责的大数据计算部分,又要依赖Hadoo ...

  5. swift-基础语法2

    一.整形 :有符号和无符号类型 有符号类型:Int ,Int8 ,Int32,Int64 无符号类型: UInt ,UInt8 UInt32,UInt64 注意点:如果你的开发环境是32位,那么Int ...

  6. 2019.02.06 bzoj4503: 两个串(fft)

    传送门 题意简述:给两个字符串s,ts,ts,t,ttt中可能有通配符,问ttt在sss出现的次数和所有位置. 思路:一道很熟悉的题,跟bzoj4259bzoj4259bzoj4259差不多的. 然后 ...

  7. ASP项目部署IIS7.5中遇到的问题

    我们大家都熟悉了tomcat服务器的部署,如果是一个ASP项目如何部署呢.这也是我在客户现场遇到的问题.ASP项目一般是用的系统组件IIS来部署项目.下面我讲一下自己在部署过程中遇到的问题. 如果在网 ...

  8. flex布局中的主轴和侧轴的确定

    1.主轴和侧轴是通过flex-direction确定的 如果flex-direction是row或者row-reverse,那么主轴就是justify-contain 如果flex-direction ...

  9. 补全爬取的url

    有时爬取到的href不全,如href=‘/11031/’解决方法:from urllib import parseurl=parse.urljoin(response.url,get_url)resp ...

  10. .net 导出Excel

    CreateExcel(ExcelDs, ", f); void CreateExcel(DataSet ds, string typeid, string FileName) { Http ...