前言
你好,我是若川。这是
学习源码整体架构
第一篇。整体架构这词语好像有点大,姑且就算是源码整体结构吧,主要就是学习是代码整体结构,不深究其他不是主线的具体函数的实现。本篇文章学习的是打包整合后的代码,不是实际仓库中的拆分的代码。
学习源码整体架构
系列文章如下:
1.学习 jQuery 源码整体架构,打造属于自己的 js 类库
2.学习 underscore 源码整体架构,打造属于自己的函数式编程类库
3.学习 lodash 源码整体架构,打造属于自己的函数式编程类库
4.学习 sentry 源码整体架构,打造属于自己的前端异常监控SDK
感兴趣的读者可以点击阅读。
虽然现在基本不怎么使用jQuery
了,但jQuery
流行10多年
的JS库
,还是有必要学习它的源码的。也可以学着打造属于自己的js
类库,求职面试时可以增色不少。
本文章学习的是v3.4.1
版本。unpkg.com
源码地址:https://unpkg.com/jquery@3.4.1/dist/jquery.js
自执行匿名函数
1 | 复制代码(function(global, factory){ |
外界访问不到里面的变量和函数,里面可以访问到外界的变量,但里面定义了自己的变量,则不会访问外界的变量。
匿名函数将代码包裹在里面,防止与其他代码冲突和污染全局环境。
关于自执行函数不是很了解的读者可以参看这篇文章。
[译] JavaScript:立即执行函数表达式(IIFE)
浏览器环境下,最后把$
和 jQuery
函数挂载到window
上,所以在外界就可以访问到$
和jQuery
了。
1 | 复制代码if ( !noGlobal ) { |
支持多种环境下使用 比如 commonjs、amd规范
commonjs 规范支持
commonjs
实现 主要代表 nodejs
1 | 复制代码// global是全局变量,factory 是函数 |
amd 规范 主要代表 requirejs
1 | 复制代码if ( typeof define === "function" && define.amd ) { |
cmd 规范 主要代表 seajs
很遗憾,jQuery
源码里没有暴露对seajs
的支持。但网上也有一些方案。这里就不具体提了。毕竟现在基本不用seajs
了。
无 new 构造
实际上也是可以 new
的,因为jQuery
是函数。而且和不用new
效果是一样的。
new显示返回对象,所以和直接调用jQuery
函数作用效果是一样的。
如果对new
操作符具体做了什么不明白。可以参看我之前写的文章。
源码:
1 | 复制代码 var |
1 | 复制代码jQuery.fn === jQuery.prototype; // true |
关于这个笔者画了一张jQuery
原型关系图,所谓一图胜千言。
1 | 复制代码<sciprt src="https://unpkg.com/jquery@3.4.1/dist/jquery.js"> |
Vue
源码中,也跟jQuery
类似,执行的是Vue.prototype._init
方法。
1 | 复制代码function Vue (options) { |
核心函数之一 extend
用法:
1 | 复制代码jQuery.extend( target [, object1 ] [, objectN ] ) Returns: Object |
jQuery.extend API
jQuery.fn.extend API
看几个例子:
(例子可以我放到在线编辑代码的jQuery.extend例子codepen了,可以直接运行)。
1 | 复制代码// 1. jQuery.extend( target) |
结论:extend
函数既可以实现给jQuery
函数可以实现浅拷贝、也可以实现深拷贝。可以给jQuery上添加静态方法和属性,也可以像jQuery.fn
(也就是jQuery.prototype
)上添加属性和方法,这个功能归功于this
,jQuery.extend
调用时this
指向是jQuery
,jQuery.fn.extend
调用时this
指向则是jQuery.fn
。
浅拷贝实现
知道这些,其实实现浅拷贝还是比较容易的:
1 | 复制代码// 浅拷贝实现 |
深拷贝则主要是在以下这段代码做判断。可能是数组和对象引用类型的值,做判断。
1 | 复制代码if ( copy !== undefined ) { |
为了方便读者调试,代码同样放在jQuery.extend浅拷贝代码实现codepen,可在线运行。
深拷贝实现
1 | 复制代码$.extend = function(){ |
为了方便读者调试,这段代码同样放在jQuery.extend深拷贝代码实现codepen,可在线运行。
深拷贝衍生的函数 isFunction
判断参数是否是函数。
1 | 复制代码var isFunction = function isFunction( obj ) { |
深拷贝衍生的函数 jQuery.isPlainObject
jQuery.isPlainObject(obj)
测试对象是否是纯粹的对象(通过 “{}” 或者 “new Object” 创建的)。
1 | 复制代码jQuery.isPlainObject({}) // true |
1 | 复制代码var getProto = Object.getPrototypeOf; |
extend
函数,也可以自己删掉写一写,算是jQuery
中一个比较核心的函数了。而且用途广泛,可以内部使用也可以,外部使用扩展 插件等。
链式调用
jQuery
能够链式调用是因为一些函数执行结束后 return this
。
比如jQuery
源码中的addClass
、removeClass
、toggleClass
。
1 | 复制代码jQuery.fn.extend({ |
jQuery.noConflict
很多js
库都会有的防冲突函数
用法:
1 | 复制代码 <script> |
jQuery.noConflict 源码
1 | 复制代码var |
总结
全文主要通过浅析了jQuery
整体结构,自执行匿名函数、无new
构造、支持多种规范(如commonjs、amd规范)、核心函数之extend
、链式调用、jQuery.noConflict
等方面。
重新梳理下文中学习的源码结构。
1 | 复制代码// 源码结构 |
可以学习到jQuery
巧妙的设计和架构,为自己所用,打造属于自己的js
类库。
相关代码和资源放置在github blog中,需要的读者可以自取。
下一篇文章是学习underscorejs
的源码整体架构。学习 underscore 源码整体架构,打造属于自己的函数式编程类库
读者发现有不妥或可改善之处,欢迎评论指出。另外觉得写得不错,可以点赞、评论、转发,也是对笔者的一种支持。
笔者往期文章
前端使用puppeteer 爬虫生成《React.js 小书》PDF并合并
扩展阅读
chokcoco: jQuery- v1.10.2 源码解读
chokcoco:【深入浅出jQuery】源码浅析–整体架构
笔者另一个系列
关于
作者:常以若川为名混迹于江湖。前端路上 | PPT爱好者 | 所知甚少,唯善学。
若川的博客,使用vuepress
重构了,阅读体验可能更好些
掘金专栏,欢迎关注~
segmentfault
前端视野专栏,欢迎关注~
语雀前端视野专栏,新增语雀专栏,欢迎关注~
知乎前端视野专栏,欢迎关注~
github blog,相关源码和资源都放在这里,求个star
^_^~
欢迎加微信交流 微信公众号
可能比较有趣的微信公众号,长按扫码关注。欢迎加笔者微信ruochuan12
(注明来源,基本来者不拒),拉您进【前端视野交流群】,长期交流学习~
若川视野
本文使用 mdnice 排版
本文转载自: 掘金