underscore.js源码研究(2)
概述
很早就想研究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)的更多相关文章
- underscore.js源码研究(8)
概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...
- underscore.js源码研究(7)
概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...
- underscore.js源码研究(6)
概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...
- underscore.js源码研究(5)
概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...
- underscore.js源码研究(4)
概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...
- underscore.js源码研究(3)
概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...
- underscore.js源码研究(1)
概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...
- underscore.js源码解析(五)—— 完结篇
最近公司各种上线,所以回家略感疲惫就懒得写了,这次我准备把剩下的所有方法全部分析完,可能篇幅过长...那么废话不多说让我们进入正题. 没看过前几篇的可以猛戳这里: underscore.js源码解析( ...
- underscore.js 源码
underscore.js 源码 underscore]JavaScript 中如何判断两个元素是否 "相同" Why underscore 最近开始看 underscore.js ...
随机推荐
- php结合layui实现前台加后台操作
一:前台加载出前端页面: HTML: lay-data="{width:800,height:400, url:'data.php', page:true, id:'test'} js: l ...
- 19 模块之shelve xml haslib configparser
shelve 什么是shelve模块 也是一种序列化方式使用方法 1.opne 2.读写 3.close特点:使用方法比较简单 提供一个文件名字就可以开始读写 读写的方法和字典一致 你可以把它当成带有 ...
- Sencha extjs 的安装
delphi 的母公司Idera 突然就把sencha extjs 收购了,这确实是一个很好的消息,意味着delphi 开始在web方面开始发力, 目前delphi 集成extjs 的呼声越来越强烈, ...
- 2018.12.15 hdu4641 K-string(后缀自动机)
传送门 后缀自动机基础题. 题意简述:支持动态在串尾插入字符,查询在串中出现超过kkk次的子串的个数. 动态修改samsamsam,每次增量构造好了之后在parentparentparent树上从新建 ...
- VMware Authorization Service不能启动 VMware虚拟机状态已挂起无法恢复解决方案
在网上看说在服务里面启动 但也是不能用 电脑上说是WINDOWS无法启动VMware Authorization Service服务(位于本地计算机上)错误:1068 依赖服务或组无法启动 这个很简单 ...
- js判断 pc 手机 浏览器
<script> var result = window.matchMedia('(max-width: 700px)'); var browser={ versions:function ...
- HTTP请求模型和头信息参考
发送HTTP请求:一个请求由四个部分组成:请求行.请求头标.空行和请求数据 请求行 请求行由三个标记组成:请求方法.请求URI和HTTP版本,它们用空格分隔.例如:GET /index.html HT ...
- (多线程dp)Matrix (hdu 2686)
http://acm.hdu.edu.cn/showproblem.php?pid=2686 Problem Description Yifenfei very like play a num ...
- CentOS 网络设置修改 2
一.CentOS 修改IP地址 修改对应网卡的IP地址的配置文件# vi /etc/sysconfig/network-scripts/ifcfg-eth0 修改以下内容 DEVICE=eth0 #描 ...
- Scala_特质
特质 特质概述 Java中提供了接口,允许一个类实现任意数量的接口 在Scala中没有接口的概念,而是提供了“特质(trait) ”,它不仅实 现了接口的功能,还具备了很多其他的特性 Scala的特质 ...