深拷贝与浅拷贝的深度理解
本文主要讲一下 js 的基本数据类型以及一些堆和栈的知识和什么是深拷贝、什么是浅拷贝、深拷贝与浅拷贝的区别,以及怎么进行深拷贝和怎么进行浅拷贝。
堆和栈的区别
其实深拷贝和浅拷贝的主要区别就是其在内存中的存储类型不同。
堆和栈都是内存中划分出来用来存储的区域。
在将深拷贝和浅拷贝之前,我们先来重新回顾一下 ECMAScript 中的数据类型。主要分为
基本数据类型主要是:undefined,boolean,number,string,null
。 基本数据类型值不可变 基本数据类型存放在栈中 基本类型的比较是值的比较 基本类型的赋值的两个变量是两个独立相互不影响的变量。
引用类型(object
)是存放在堆内存中的,引用类型值可变 引用类型的比较是引用的比较(对象在堆内存的引用地址)
浅拷贝 :只复制一层对象的属性 对于 简单数据类型的数据 (直接复制) 所以拷贝前后没有影响 对于复杂数据类型 由于只拷贝了引用地址 所以复制后 对新对象进行修改 可 能会影响原对象
深拷贝 :开辟一个新的内存空间,存储空新对象(与源对象无关),然后递归遍历源对象结构(直到源对象都为基本数据类型),然后进行给空对象的复制操作
深拷贝的代码
1 // 旧对象 2 let oldObj = { 3 name: "张三", 4 age: 18, 5 sex: "男", 6 hobbies: { weight: 175 }, 7 color: ["pink", "red", "blue"], 8 }; 9 // 新对象 10 let newObj = {}; 11 // 定义deepCopy函数 12 function deepCopy(newObj, oldObj) { 13 for (var key in oldObj) { 14 // 拿到属性值 15 var item = oldObj[key]; 16 // 判断属性值是不是数组 ---先判断数组 再判断对象 17 if (item instanceof Array) { 18 // 递归调用 遍历结构 19 newObj[key] = []; 20 deepCopy(newObj[key], item); 21 } else if (item instanceof Object) { 22 // 判断属性值是不是对象 23 newObj[key] = {}; 24 deepCopy(newObj[key], item); 25 } else { 26 // 值类型为基本类型了 进行赋值操作 27 newObj[key] = item; 28 } 29 } 30 // 返回新的数据对象 31 return newObj; 32 } 33 // 调用深度拷贝函数 34 deepCopy(newObj, oldObj); 35 console.log(newObj);
浅拷贝的代码
1 // 旧的对象 2 let obj = { 3 name: "zhangsan", 4 age: 18, 5 hobbies: { 6 weight: 175, 7 }, 8 }; 9 // 新的对象 10 let o = {}; 11 12 // es6语法糖 浅拷贝 13 let res = Object.assign(o, obj); 14 console.log(res); 15 16 // for in可实现浅拷贝 17 for (var key in obj) { 18 // k是属性名 obj[k] 属性值 19 o[key] = obj[key]; 20 } 21 22 console.log(o);