复制引用类型的时候,复制的是引用地址,而不是新建一个内存。这是浅拷贝。
那我们要实现它的深拷贝。
可以看到最终拷贝的结果是null、undefinde、function、RegExp等特殊的值也全部拷贝成功了,而且我们修改里边的值也不会有任何问题的
缺点:
(1)无法保持引用
(2)当数据的层次很深,会栈溢出
// 定义一个深拷贝函数 接收目标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])) } // 判断如果当前的值是null的话;直接赋值为null } else if(target===null) { result = null; // 判断如果当前的值是一个RegExp对象的话,直接赋值 } else if(target.constructor===RegExp){ result = target; }else { // 否则是普通对象,直接for in循环,递归赋值对象的所有值 result = {}; for (let i in target) { result[i] = deepClone(target[i]); } } // 如果不是对象的话,就是基本数据类型,那么直接赋值 } else { result = target; } // 返回最终结果 return result; }如果对象中不含函数的话,可以通过json拷贝实现。不可以拷贝undefined、function,RegExp等类型的。
缺点:
(1)如果对象里有函数,函数无法被拷贝下来
(2)无法拷贝copyObj对象原型链上的属性和方法
(3)当数据的层次很深,会栈溢出
function (obj) { let tmp = JSON.stringify(obj); let result = JSON.parse(tmp); return result; }只能单层嵌套,如果有多层,无法实现嵌套。
//单层嵌套例子 var obj1 = { a: 1, b: 2, c: 3 } var obj2 = Object.assign({}, obj1); obj2.b = 5; console.log(obj1.b); // 2 console.log(obj2.b); // 5 //多层嵌套例子 var obj1 = { a: 1, b: 2, c: ['a','b','c'] } var obj2 = Object.assign({}, obj1); obj2.c[1] = 5; console.log(obj1.c); // ["a", 5, "c"] console.log(obj2.c); // ["a", 5, "c"]lodash很热门的函数库,提供了 lodash.cloneDeep()实现深拷贝