lodash 对 clone
的定义
这个方法参考自structured clone algorithm 以及支持 arrays、array buffers、 booleans、 date objects、maps、 numbers, Object 对象, regexes, sets, strings, symbols, 以及 typed arrays。 arguments对象的可枚举属性会拷贝为普通对象。 一些不可拷贝的对象,例如error objects、functions, DOM nodes, 以及 WeakMaps 会返回空对象。
-
对非
object
类型直接返回原始值,如
undefined, null, number, boolean, string,
-
对包装类型和预设的对象
- 先判断对象具体类型
T
- 然后
new
出匹配的空对象O
- 用原始对象的值
TVal
来赋值O
目前支持的类型:
Number, Boolean, String, NaN, Infinity, Array, Arguments, Date, Set, Map
- 先判断对象具体类型
-
自定义对象
-
根据对象
O
的[[prototype]]
构造出对象V
V = Object.create(prototypeOf(O))
-
将原始对象的成员变量逐个赋值到新的对象
for(ownProp in V) V[ownProp] = O[ownProp]
-
-
在浅拷贝的基础上,在每次赋值前,对值本身做一次拷贝,也就是递归拷贝
V[ownProp] = clone( O[ownProp] )
-
解决循环引用
一些复杂的对象,在内部会有相互引用的关系,为了能在拷贝的对象中保持应用关系,我们需要:
- 缓存拷贝前后的对象
OC = Map{O -> V}
- 在递归拷贝每个对象之前,判断原始对象是否存在于缓存中
OC.has(O)
-
如果存在,择使用
V
赋值给新对象V[ownProp] = oc.get(O)
-
如果不存在
N = clone( O[ownProp] ) OC.set(O, N) V[ownProp] = N
-
- 缓存拷贝前后的对象
-
关于缓存对象
OC
lodash
的缓存实现是Map
, 这里替换成了性能和GC
更友好的WeakMap