学习underscore源码整体架构,打造属于自己的函数式编程类库

栏目: IT技术 · 发布时间: 4年前

内容简介:前言上一篇文章写了虽然看过挺多

前言

上一篇文章写了 jQuery整体架构 ,学习 jQuery 源码整体架构,打造属于自己的 js 类库

虽然看过挺多 underscore.js 分析类的文章,但总感觉少点什么。这也许就是 纸上得来终觉浅,绝知此事要躬行 吧。于是决定自己写一篇学习 underscore.js 整体架构的文章。

本文章学习的版本是 v1.9.1unpkg.com 源码地址:https://unpkg.com/underscore@1.9.1/underscore.js

虽然很多人都没用过 underscore.js ,但看下官方文档都应该知道如何使用。

从一个官方文档 _.chain 简单例子看起:

看例子中可以看出,这是支持链式调用。

读者也可以顺着文章思路,自行打开下载源码进行调试,这样印象更加深刻。

链式调用

_.chain 函数源码:

这个函数比较简单,就是传递 obj 调用 _() 。但返回值变量竟然是 instance 实例对象。添加属性 _chain 赋值为 true ,并返回 intance 对象。但再看例子,实例对象竟然可以调用 reverse 方法,再调用 value 方法。猜测支持 OOP (面向对象)调用。

带着问题,笔者看了下定义 _ 函数对象的代码。

_ 函数对象 支持  OOP

如果参数 obj 已经是 _ 的实例了,则返回 obj 。如果 this 不是 _ 的实例,则手动 new_(obj) ; 再次 new 调用时,把 obj 对象赋值给 _wrapped 这个属性。也就是说最后得到的实例对象是这样的结构 {_wrapped:'参数obj',} 它的原型 _(obj).__proto___.prototype ;

如果对这块不熟悉的读者,可以看下以下这张图(之前写面试官问: JS的继承 画的图)。 学习underscore源码整体架构,打造属于自己的函数式编程类库

继续分析官方的 _.chain 例子。这个例子拆开,写成三步。

思考问题: reverse 本是 Array.prototype 上的方法呀。为啥支持链式调用呢。搜索 reverse ,可以看到如下这段代码:

并将例子代入这段代码可得(怎么有种高中做数学题的既视感^_^):

if((name==='shift'||name==='splice')&&obj.length===0)deleteobj[0]; 提一下上面源码中的这一句,看到这句是百思不得其解。于是赶紧在 github 中搜索这句加上 "" 双引号。表示全部搜索。

搜索到两个在官方库中的 ISSUE ,大概意思就是兼容IE低版本的写法。有兴趣的可以点击去看看。

I don't understand the meaning of this sentence.

why delete obj[0]

基于流的编程

至此就算是分析完了链式调用 _.chain()_ 函数对象。这种把数据存储在实例对象 {_wrapped:'',_chain:true} 中, _chain 判断是否支持链式调用,来传递给下一个函数处理。这种做法叫做 基于流的编程

最后数据处理完,要返回这个数据怎么办呢。 underscore 提供了一个 value 的方法。

顺便提供了几个别名。 toJSONvalueOf 。_.prototype.valueOf = _.prototype.toJSON = _.prototype.value;

还提供了 toString 的方法。

这里的 String()newString() 效果是一样的。可以猜测内部实现和 _ 函数对象类似。

细心的读者会发现 chainResult 函数中的 _(obj).chain() ,是怎么实现实现链式调用的呢。

_(obj) 是返回的实例对象 {_wrapped:obj} 呀。怎么会有 chain() 方法,肯定有地方挂载了这个方法到 _.prototype 上或者其他操作,这就是 _.mixin()

_.mixin 挂载所有的静态方法到  _.prototype , 也可以挂载自定义的方法

_.mixin 混入。但侵入性太强,经常容易出现覆盖之类的问题。记得之前 Reactmixin 功能, Vue 也有 mixin 功能。但版本迭代更新后基本都是慢慢的都不推荐或者不支持 mixin

_mixin(_) 把静态方法挂载到了 _.prototype 上,也就是 _.prototype.chain 方法 也就是 _.chain 方法。

所以 _.chain(obj)_(obj).chain() 效果一样,都能实现链式调用。

关于上述的链式调用,笔者画了一张图,所谓一图胜千言。

学习underscore源码整体架构,打造属于自己的函数式编程类库

_.mixin 挂载自定义方法

挂载自定义方法:举个例子:

_.functions(obj)

_.functions_.methods 两个方法,遍历对象上的方法,放入一个数组,并且排序。返回 排序 后的数组。

underscore.js 究竟在  _ 和  _.prototype 挂载了多少方法和属性

再来看下 underscore.js 究竟挂载在 _函数对象 上有多少静态方法和属性,和挂载 _.prototype 上有多少方法和属性。

使用 forin 循环一试遍知。看如下代码:

根据这些,笔者又画了一张图 underscore.js 原型关系图,毕竟一图胜千言。

学习underscore源码整体架构,打造属于自己的函数式编程类库

整体架构概览

匿名函数自执行

这样保证不污染外界环境,同时隔离外界环境,不是外界影响内部环境。

外界访问不到里面的变量和函数,里面可以访问到外界的变量,但里面定义了自己的变量,则不会访问外界的变量。匿名函数将代码包裹在里面,防止与其他代码冲突和污染全局环境。关于自执行函数不是很了解的读者可以参看这篇文章。[译] JavaScript:立即执行函数表达式(IIFE)

root 处理

支持 浏览器环境nodeWebWorkernode vm微信小程序

导出

关于 root处理导出 的这两段代码的解释,推荐看这篇文章冴羽:underscore 系列之如何写自己的 underscore,讲得真的太好了。笔者在此就不赘述了。总之, underscore.js 作者对这些处理也不是一蹴而就的,也是慢慢积累,和其他人提 ISSUE 之后不断改进的。

支持 amd 模块化规范

_.noConflict 防冲突函数

源码:

使用:

总结

全文根据官网提供的链式调用的例子, _.chain([1,2,3]).reverse().value(); 较为深入的调试和追踪代码,分析链式调用( _.chain()_(obj

).chain() )、 OOP 、基于流式编程、和 _.mixin(_)_.prototype 挂载方法,最后整体架构分析。学习 underscore.js 整体架构,利于打造属于自己的函数式编程类库。

文章分析的源码整体结构。

下一篇文章可能是学习 lodash 的源码整体架构。

读者发现有不妥或可改善之处,欢迎评论指出。另外觉得写得不错,可以点赞、评论、转发,也是对笔者的一种支持。

了方便进行探讨和交流,我为大家建立了一个读者群,一起学习,一起进步。

学习underscore源码整体架构,打造属于自己的函数式编程类库

:heart:爱心三连击

1.看到这里了就点个在看支持下吧,你的 「在看」 是我创作的动力。

2.关注公众号 达达前端「每天为您分享原创或精选文章」

3.特殊阶段,带好口罩,做好个人防护。

4.添加微信【xiaoda0423】,拉你进 技术交流群 一起学习

扫码关注公众号,订阅更多精彩内容。

学习underscore源码整体架构,打造属于自己的函数式编程类库

好文章,我 在看


以上所述就是小编给大家介绍的《学习underscore源码整体架构,打造属于自己的函数式编程类库》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

How Tomcat Works

How Tomcat Works

Budi Kurniawan、Paul Deck / BrainySoftware / 2004-4-1 / USD 54.95

A Guide to Developing Your Own Java Servlet Container一起来看看 《How Tomcat Works》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具