前言
在js中我们想要实现深拷贝,首先要了解深浅拷贝的区别。
浅拷贝:只是拷贝数据的内存地址,而不是在内存(堆)中重新创建一个一模一样的对象(数组)
深拷贝:在内存中开辟一个新的存储空间,完完全全的拷贝一整个一模一样的对象(数组)。
方案一(JSON方案)
// 1. 需要深拷贝的数据源
const obj = {
id: 1,
name: 'andy',
reg: /_^/,
a: null,
b: undefined,
msg: {
age: 18
},
color: ['orange', 'blue'],
callBack: function () {
alert(123)
}
}
// 2. 方案一: 通过JSON方式解决
const newObj = JSON.parse(JSON.stringify(obj))
console.log('~', obj)
console.log('@', newObj)
![](https://i-blog.csdnimg.cn/blog_migrate/2603ac37ef3d6702f1fb736fb5445c14.png)
局限性: 不能正常拷贝函数、RegExp、undefined等等...(要么被舍弃、要么拷贝为一个空对象)
方案二(递归实现:解决不能拷贝函数的问题)
// 1. 需要深拷贝的数据源
const obj = {
id: 1,
name: 'andy',
reg: /_^/,
a: null,
b: undefined,
msg: {
age: 18
},
color: ['orange', 'blue'],
callBack: function () {
alert(123)
}
}
// 2. 对函数的深拷贝方法
function cloneFunction(fn) {
// 1.将函数转换为字符串
const str = fn.toString()
// 2.提取函数中的自定义代码片段
const funStr = str.substring(str.indexOf('{') + 1, str.indexOf('}'))
// 3.重新创建一个函数将用户自定义代码片段传入
return new Function(funStr)
}
// 3. 递归实现深拷贝
function deepClone(originObj) {
// 1.判断是否为简单类型就数据(简单判断)
if (!(originObj instanceof Array) && !(originObj instanceof Object)) {
return originObj
}
const targetObj = originObj instanceof Array ? [] : {}
for (const key in originObj) {
if (originObj.hasOwnProperty(key)) {
const value = originObj[key]
if (value instanceof Function) {
targetObj[key] = cloneFunction(value)
} else if (value instanceof Array || value instanceof Object) {
targetObj[key] = deepClone(value)
} else {
targetObj[key] = value
}
}
}
return targetObj
}
const obj2 = deepClone(obj)
console.log(deepClone(2))
console.log('~', obj)
console.log('@', obj2)
console.log(obj.callBack === obj2.callBack)
obj2.callBack()
输出结果
![](https://i-blog.csdnimg.cn/blog_migrate/8384c5942adb79494488bb14ed6e236e.png)
![](https://i-blog.csdnimg.cn/blog_migrate/8fe5121cabeb4da27c23aa1da84a9f08.png)
这样就可以解决不能拷贝函数的问题了,可以利用类似的思想解决不能拷贝正则对象等其他的问题。
但是这样出现了一个新的问题,拷贝后的函数为匿名函数(不知道为什么),期待大佬来解答!!!!!!!!!!!