ECMAScript|js中对象和数组的浅拷贝与深拷贝(ES6、前端面试常用)

在ES6中扩展操作符(…)与Object.assign()中复制是浅拷贝,所谓的浅拷贝和深拷贝:

【ECMAScript|js中对象和数组的浅拷贝与深拷贝(ES6、前端面试常用)】浅拷贝,是在拷贝过程中,遍历时那部分为对象/数组类型指向原来的地址。即修改其中任意的值,另一个值都会随之变化
深拷贝,则是完全开辟新的内存地址。即将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变
1、浅拷贝
浅拷贝: 只做一个最外层的拷贝. 如果拷贝的对象是引用型数据类型,则意味着交出了内存地址,因而在浅拷贝成功的对象身上对引用型数据进行修改时,就会影响到 原来的拓本
let obj = { a: 1, b: [1, 2, {a:3}], c: {a:3} } obj.c.a = 4let obj1 = { a: obj.a, b: obj.b } obj1.b.push(1) // 切记不要 obj1.b = 123 这样是重新赋值 不是改变原地址的对象 console.log(obj.b) //将会被改变ES6方法: let obj2 = Object.assign({},obj) console.log(obj2)//{a: 1,b: [1, 2, {a:3}],c:{a:4}展开操作符: let obj3 = {...obj} conosle.log(obj3) //{a: 1,b: [1, 2, {a:3}],c:{a:4}


2、深拷贝
深拷贝: 里里外外全部拷贝,完全复制,保证引用型数据 依旧是引用型,但不拿地址,只模仿你的面,因此扩展上没有问题,不会冲突
let obj1 = { a: 1, b: [1, 2, {a:3}], c: {a:3} } //完全复制 完美复制 但是一个一个去复制,太麻烦啦 我们来一个专门深浅复制的函数obj1.c.a = 4let obj2 = JSON.parse(JSON.stringify(obj1)) console.log(obj2)//{a: 1,b: [1, 2, {a:3}],c:{a:3}


自制深复制函数
1.需求参数1传入拓本输出拷贝品 let obj = { //拓本 a: 1, b: [1,2,3,{a: "我"}], c: {d: 5} } function extend (o1) { var obj1 = {} if (o1 instanceof Array) { //判断对象是否是数组 obj1 = [] } for(var key in o1){ var value = https://www.it610.com/article/o1[key] // 拓本中的值 // value内还有引用型数据&& value不为 null 则 需要对value这个对象 再进来 深拷贝一份 返回出来深拷贝后的值 // obj1[key] = extend(value) if(typeof value ==="object" && value !== null){ obj1[key] = extend(value) }else{ obj1[key] = value } } return obj1 }let obj2 = extend(obj)// 深拷贝测试 obj2.b.push("最后") console.log(obj2) console.log(obj) // 深拷贝 不影响拓本浅拷贝 拓本一起变

    推荐阅读