Vuex@next源码解析 - 工具函数篇篇
前言
工具函数还是放在一起写,不然感觉有时候写重点的时候,遇到工具函数,要花篇幅去解释会使得文章断层…
工具函数基本在src
的utils.js
文件下
Vuex
工具函数
find
1 | export function find (list, f) { |
看他的实现可以看出使用了数组的filter
来模拟寻找一个元素
1 | find([1, 2, 3, 4], val => val > 2); // 输出3 |
其实感觉可以使用es6
的数组方法find
的,也能有一样的效果
1 | [1, 2, 3, 4].find(val => val > 3); // 输出3 |
可能是为了兼容性考虑吧,filter
在es5
中就已经支持了,而find
是es6
才有的
forEachValue
1 | export function forEachValue (obj, fn) { |
对对象进行遍历,传入的回调第一个参数为属性值,第二个参数为属性名
1 | forEachValue({ |
效果图
这个函数在Vuex
的主要代码中使用比较多
isObject
1 | export function isObject (obj) { |
判断是否为对象,注意js中typeof null === 'object'
,所以null
的情况要排除
isPromise
1 | function isPromise (val) { |
Promise/A+
规范并没规定如何生成一个Promise
规范只定义了then
函数的行为,这里满足存在then
函数,即可认为它是一个Promise
这算是一种比较宽松的判断吧
assert
1 | export function assert (condition, msg) { |
这个函数是Vuex
用来断言的一个工具函数,通过condition
参数为false
就抛出错误,统一以[vuex]
为前缀字符串
partial
1 | export function partial (fn, arg) { |
这个函数从名字看挺迷惑的,partial
意思:部分的,不完全的
emmm,好吧,单纯从名字看无法推出函数内容
但是从实现看就非常清楚了,这不就是绑定函数的参数然后延迟这个函数的执行吗
deepCopy
1 | export function deepCopy (obj, cache = []) { |
这个函数应该是这个工具函数中最有意思的了吧,这个函数根据名字上看就是深拷贝的意思、
函数有注释,如下
Deep copy the given object considering circular structure.
This function caches all nested objects and its copies.
If it detects circular structure, use cached copy to avoid infinite loop.
大概意思是,深拷贝传入的对象,并且考虑到循环引用的情况
这个函数缓存了所有嵌套的对象和他的拷贝
如果发现存在循环引用,使用缓存的拷贝来避免无限的循环
1 | // just return if obj is immutable value |
第一个判断好理解,如果传入的不是一个对象,那么直接返回即可,这里包括了null
1 | deepCopy(1); // 返回1 |
1 | // if obj is hit, it is in circular structure |
第二部分会在cache
数组中查找是否已经登记过这个对象了
如果登记过了,那么此时就是不应该拷贝这个对象了,直接返回它前面登记的拷贝对象
1 | const copy = Array.isArray(obj) ? [] : {} |
这一段就是把拷贝的对象和原对象登记到cache
数组里面
这里可以看出这个深拷贝只支持字面对象和数组,不支持Set
或者Map
等
不过我感觉这也涵盖了许多的情况了,通用性感觉还是挺高的
1 | Object.keys(obj).forEach(key => { |
接着就是通过Object.keys
来递归的深拷贝每个属性对应的值,然后返回当前的拷贝出来的对象
整体上我们可以测试下
1 | const o = { |
测试如下
后记
目前Vuex
的源码解析的文章还在改进中,如果你幸运地来到了这里,也对我的帖子感兴趣,
那么请再给我一点时间,让我更好地整理和调整文章的细节,谢谢😘