jQuery为开发者提供了快速便捷
的DOM操作, 那么如果我们想添加自己的方法到jQuery原型或者构造函数上, 我们该怎么做呢? jQuery暴露出了extend
API来解决这个问题, 这篇文章就来观摩一下其拓展机制
.
一、更新
[2019-4-21]
Changed
- 改进文章格式🎉
二、前置
2.1 深拷贝vs浅拷贝
PS: 关于
深
、浅
拷贝的知识, 网上的各种博客已经层出不穷了, 对其实现方式
以及基本原理
都讲解的很清楚. 这里还是苦口婆心
地提一下, 它们的主要区别, 也是为了接下来地阅读作个铺垫吧.
那么, 问题来了:
Q: 两者的
主要
区别是什么?
- 对于
数组
, 两者是一样的功能 - 对于
键值对对象
shallowCopy
只拷贝Object.keys()
, 也就是第一层键值
deepCopy
则反之
一个简单的例子:
1 | const obj = { |
关于它们的区别, 还可以参考我之前的文章:
PS: 前端基础重拾系列之——深浅拷贝
三、用法
3.1 jQuery.extend&jQuery.fn.extend
jq提供了两种方式, 供我们自定义拓展:
- jQuery.extend(…)
- 拓展
Static
, 也就是静态方法
- 拓展
- jQuery.fn.extend(…)
- 拓展
Non-static
(实例方法)
- 拓展
3.2 如何使用?
分析拓展机制
前, 先做一件事情, 那就是如何去使用它, 俗话说知其意,悟其理,守其则,践其行
, 了解了它是如何使用
, 再去深究其原理
, 这也是我写文章的一贯原则.
PS: 自己用
jQuery
很少, 所以对extend
API也基本没用过, 但是这并不影响对其理解, 毕竟知识是相通的, 所谓的框架只不过是换了身皮
.
一般来说, 开发者可以根据可以传递的参数个数不同
, 通过下述三种方式使用(以jQuery.fn.extend
)为例:
3.2.1 使用方式一
PS: 给jq原型添加方法. jQuery的各种
plugin
就是通过如此来挂载
1 | $.fn.extend({ |
还有另一种方式, 那就是通过直接赋值
的方式来拓展:
1 | $.fn['sayHello'] = function() { |
3.2.2 使用方式二
PS: 合并
后续
对象到首个
对象, 纯粹返回一个拓展后的对象, 此时与jQuery
没有任何关系.
1 | const origin = {}; |
3.2.3 使用方式三
PS: 是否执行深层的
copy
操作.
1 | const origin = {}; |
四、细说
PS: 对于内部的全部代码逻辑, 我觉得并没有必要细看, 所以这里只选取了一种情况————
单个参数
, 也就是对于拓展jQuery原型
or静态方法
的处理.
4.1 贴源码
先来贴一下部分源码:
1 | jQuery.extend = jQuery.fn.extend = function() { |
4.2 析源码
对于单个参数的处理逻辑很简单:
- 将
target
赋值为this, this有两种情况- jQuery构造函数
- jQuery实例
for-in
遍历options
- 给
target
赋值- 过滤掉
target
的值为undefined
的情况
- 过滤掉
五、总结
jQuery提供的extend
极大地方便了开发者, 同样的, var
框架同样有对应的拓展方法, 这里就不说了(其实是太菜了).
当然, 最近也在挤时间看react
源码, 感觉其复杂度高了几个层级, 所以还是一步一步地走下去吧!
五、示例代码
使用ts
重构了我之前写的jQuery类库
, 项目地址戳这里