本文共 1871 字,大约阅读时间需要 6 分钟。
JS中,数据类型分为基本数据类型和引用数据类型。基本数据类型的值是存储在栈内存中的;而引用数据类型的值是存储在堆内存中的,栈中只存储对象在堆中的内存地址
对于浅拷贝而言,就是只拷贝对象的引用,而不深层次的拷贝对象的值,多个对象指向堆内存中的同一内存地址,任何一个对象修改值都会影响其他的对象
深拷贝作用在引用类型上,例如:Object,Array。
var obj1 = { a: 1, b: 2, c: 3}var objString = JSON.stringify(obj1);var obj2 = JSON.parse(objString);obj2.a = 5;console.log(obj1.a); // 1console.log(obj2.a); // 5
该方法的缺点:
无法拷贝 undefined , function, RegExp 等类型的值对象中所有属性均为基本数据类型时,可正确拷贝
var obj1 = { a: 1, b: 2, c: 3}var obj2 = Object.assign({}, obj1);obj2.b = 5;console.log(obj1.b); // 2console.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"]
该方法的缺点:
如果对象中有属性为引用数据类型时,该方法还是只拷贝了引用。若修改该属性中的值还是会影响到其他对象(1)能够保证拷贝的结果是null、undefinde、function、RegExp等特殊的值也全部拷贝成功;
(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;}
转载地址:http://metii.baihongyu.com/