【JavaScript】深拷贝
为了实现一个函数 clone ,可以对 JavaScript 中 5 种主要的数据类型 (包括 Number、 String 、 Object、 Array、 Boolean )进行值(深)复制。
思路解释
首先根据题意要对5种数据类型进行深拷贝,那么就必须首先进行判断其为数据类型,使用instanceof进行判断,然后要对其进行分类复制,因为不仅要对表层数据进行拷贝,还要对包含在内的元素进行深拷贝,因此就需要使用到递归,通过递归实现深层次的拷贝(比如Object),拷贝后返回值存储在其浅层的索引中,最后等调用栈中的所有递归函数执行完毕,返回result,即完成了深拷贝,也称为深复制
代码实现
function clone(obj) {
var result
if (obj instanceof Array) {
var i = obj.length
result = [] // 向空的数组中复制内容
while (i--) {
result[i] = clone(obj[i]) // 递归克隆返回值
}
return result
} else if (obj instanceof Object) {
result = {} // 向空的对象中复制内容
for (let k in obj) {
result[k] = clone(obj[k]) // 递归克隆返回值
}
return result
} else {
return (result = obj) // 值类型直接返回
}
}
var arr = [1, { a: 100 }, null]
var obj = { a: 100, b: true, c: { d: 'Hello' } }
var num = 200
console.log(clone(arr))
console.log(clone(obj))
console.log(clone(num))
完整实现
完整实现需要对所有数据类型进行判断,包括函数、日期对象、正则等。
function deepClone(obj) {
// 过滤特殊情况
if (obj === null) return null
if (typeof obj !== 'object') return obj
if (obj instanceof RegExp) {
return new RegExp(obj)
}
if (obj instanceof Date) {
return new Date(obj)
}
if (obj instanceof Function) {
return new Function(obj)
}
// let newObj = {}
// let newObj = new Object()
// 不直接创建空对象目的:克隆的结果和之前保持相同的所属类
let newObj = new obj.constructor()
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key])
}
}
return newObj
}
var obj = { a: 100, b: [1, 2, 3], c: { d: 'Hello' }, d: /^\d+$/ }
let obj2 = deepClone(obj)
console.log(obj, obj2)
console.log(obj === obj2)
console.log(obj.c === obj2.c)