JavaScript 之 深拷贝
1.使用 JSON.parse(JSON.stringify(obj))
var obj={ a:1, b:2, c:undefined, d:function(){ console.log("ddd") }, } console.log("obj----------------",obj) let obj2=JSON.parse(JSON.stringify(obj)) console.log("obj2---------------",obj2)
这种方式不可以拷贝 undefined , function, RegExp 等等类型的,原理就是数据类型发生变化后 就和原数据无关了,数据类型变化本身就是在深拷贝了。
2.使用Object.assign(target, source);
var obj={ a:1, b:2, c:[1,2,3,4] } var obj2 = Object.assign({},obj) console.log("obj------------",obj) obj2.c[0]=99 console.log("obj2-----------",obj2)
这种方式如果对象的属性对应的是其它的引用类型的话,还是只拷贝了引用,修改的话还是会有问题,Object.assign方法用来将源对象 “obj” 的所有可枚举属性,复制到目标对象"{}"。它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。简单的来说就是把第二个对象里面的数据,拷贝到第一个空对象里面。
3.使用 递归拷贝
// 定义一个深拷贝函数 接收目标target参数 function deepClone(target) { let result; // 定义一个变量 if (typeof target === 'object') { // 如果当前需要深拷贝的是一个对象的话 if (Array.isArray(target)) { // 如果是一个数组的话 result = []; // 将result赋值为一个数组,并且执行遍历 for (let i in target) { // 递归克隆数组中的每一项 result.push(deepClone(target[i])) } } else if(target===null) { // 判断如果当前的值是null的话;直接赋值为null result = null; } else if(target.constructor===RegExp){ // 判断如果当前的值是一个RegExp对象的话,直接赋值 result = target; }else { // 否则是普通对象,直接for in循环,递归赋值对象的所有值 result = {}; for (let i in target) { result[i] = deepClone(target[i]); } } } else { // 如果不是对象的话,就是基本数据类型,那么直接赋值 result = target; } return result; // 返回最终结果 } var obj={ a:1, b:null, c:function(){ console.log("cccc") }, d:/d/ } var obj2=deepClone(obj) obj2.b={ b1:111 } obj2.a=undefined obj2.c=function(){ console.log("这是新的CCCCC") } console.log("obj--------------",obj) console.log("obj2-------------",obj2) console.log("obj.c()----------",obj.c) console.log("obj2.c()---------",obj2.c)
可以看到最终拷贝的结果是null、undefinde、function、RegExp等特殊的值也全部拷贝成功了,而且我们修改里边的值也不会有任何问题的