Loading... **前言** > 为什么需要深浅拷贝? - 首先js的数据值按照类型主要分为两大类,基本数据类型和引用数据类型。 - 基本数据类型包括Undefined、Null、Number、String、Boolean、Symbol,引用数据类型则为Object,那些Array、Set、Map数据也属于Object。 - 基本数据类型为直接赋值 - 引用类型则赋值为内存地址,为了不让拷贝后的新数据与就数据相互影响,就需要进行深拷贝 ### 浅拷贝 #### ES3 实现浅拷贝 ```js let oldObj = { a:1, b:2 } let newObj = {} for (const key in oldObj ) { newObj[key] = oldObj[key] } console.log(newObj) //{a: 1, b: 2} ``` #### ES6 实现浅拷贝 ```js let oldObj = { a:1, b:2 } let newObj = {} for (const iterator of Object.keys(oldObj)) { newObj[iterator] = oldObj[iterator] } console.log(newObj) //{a: 1, b: 2} ``` #### ES6 解构赋值 ```js let a = { m:2, n:3 } let b = {...a} a.m = 76 console.log(b) ``` ### 深拷贝 #### 利用递归进行深拷贝 ```js let a = { b:{ c:{ d:1, e:[1,2,3] } }, f:12 } let b function copy(oldObj) { let newVal if ( typeof oldObj ==='object') { // 值对象或数组时进行遍历递归,确保每一层都进行深拷贝 newVal = Array.isArray(oldObj) ? [] :{} for (let key in oldObj) { newVal[key] = copy(oldObj[key]) } } else { newVal = oldObj // 终止条件 } return newVal } obj = copy(a) a.b.c.e[1] = 67 console.log(a) console.log(b) ``` 我们可以看到即使更改了a.b.c.e[1]的值,也并不会影响b  #### 使用JSON互转 > 这个方法就属于取巧了,因为只能实现一些不是那么复杂的数据类型的深拷贝 - 对象中不能有函数,否则无法序列化 - 对象中不能有undefined,否则无法序列化 - 对象中不能有RegExp正则,否则无法序列化 - Date类型数据会被转化为字符串类型 - 对象不能是环状结构的,否则会导致报错 ```js let a = { b:{ c:{ d:1, e:[1,2,3] } }, f:12 } let obj = JSON.parse(JSON.stringify(a)) a.b.c.e[1] = 67 console.log(a) console.log(obj) ```  最后修改:2022 年 12 月 07 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏