最近项目需要用到深拷贝,不想去单独安装一个库,就自己手写了。
支持基本数据,null,undefined,布尔,数字,字符串。支持Object类型的 Map,Set,Promise,正则,日期,函数,数组,Object 类型数据。另外也支持里面数据内有属性是引用的。
let _toString = Object.prototype.toString
function isPrimitive(val) {
if (val === null) {
return true
}
return !(typeof val === 'object' || typeof val === 'function')
}
function getRegExpFlags(re) {
let flags = ''
if (re.global) flags += 'g'
if (re.ignoreCase) flags += 'i'
if (re.multiline) flags += 'm'
return flags;
}
function deepClone(obj) {
if (isPrimitive(obj) || typeof obj == 'function') {
return obj
}
let everyVal = []
let result = undefined
if (obj instanceof Map) {
result = new Map()
} else if (obj instanceof Set) {
result = new Set()
} else if (obj instanceof Promise) {
result = new Promise(function (resolve, reject) {
obj.then(function (value) {
resolve(deepClone(value))
}, function (err) {
reject(deepClone(err))
})
})
} else if (Array.isArray(obj)) {
result = []
} else if (_toString.call(obj) === '[object RegExp]') {
result = new RegExp(obj.source, getRegExpFlags(obj))
if (obj.lastIndex) result.lastIndex = obj.lastIndex
} else if (_toString.call(obj) === '[object Date]') {
result = new Date(obj.getTime())
} else if (obj instanceof Error) {
result = Object.create(obj)
} else {
let proto = Object.getPrototypeOf(obj)
result = Object.create(proto)
}
let index = everyVal.indexOf(obj)
if (index !== -1) {
return everyVal[index]
}
everyVal.push(obj)
for (let k in obj) {
result[k] = deepClone(obj[k])
}
return result
}