看了一些博客和代码后,总结一下:
第一层境界:JSON.parse(JSON.stringify)
巧妙利用JSON, 但是也受限于json,只支持json内的数据类型:Boolean,Null,Number,String,Object;Object只是普通的字面量对象以及嵌套字面量对象,Boolean,Null,Number,String的Object,不包括Function,RegExp,Date等等
第二层境界:30-seconds-of-code/deepClone
先来个有意思的表达式: Array.from(Object.assign({length: 2}, [1, 2]))
巧妙利用 Object.assign
+ Array.from
,凡是继承于Object的Function, Date, Error, RegExp, Symbol, Map, WeakMap都可以实现深clone,以及(类)数组: arguments,Array,Set,WeakSet,ES7+的ArrayBuffer,DataView,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array, Uint8Array, Uint8clampedArray, Uint16Array, Uint32Array
function deepClone (obj) {
const clone = Object.assign({}, obj)
Object.keys(clone).forEach(
key => (clone[key] = typeof clone[key] === 'object' ? deepClone(obj[key]) : obj[key])
)
return Array.isArray(obj) ? (clone.length = obj.length) && Array.from(clone) : clone
}
复制代码
第三层境界:Lodash-deepClone,
支持的数据类型是在第二层境界里面提及的一致,但是实现方式不一样,Lodash针对细分的不同数据类型会有不同的clone逻辑,分在不同的子文件,比如:
function cloneRegExp (regexp) {
const result = new regexp.constructor(regexp.source, reFlags.exec(regexp))
result.lastIndex = regexp.lastIndex
return result
}
export default cloneRegExp
复制代码
第四层境界: 考虑循环引用
在第二种,第三种的境界上考虑递归爆栈,循环引用,引用丢失的情况如何处理,掘金上的这一篇文章讲的我头大,此乃第四种境界