js深浅拷贝

对象类型在赋值的过程中其实是复制了地址,这样会导致一方改变的时候其他地方也都会被改变的情况 例: let a = { age: 1 } let b = a; a.age = 2; console.log(b.age); // 2 这种情况下我们就可以使用浅拷贝来解决这个问题 浅拷贝 浅拷贝只是拷贝基本类型的数据,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,因此存在父对象被篡改的可能,浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存 1、Object.assign 这个属性并不是用来实现深拷贝的,相反可以用来实现浅拷贝。Object.assign只会拷贝所有的属性到新的对象中,如果属性值是对象的活,拷贝的就是地址,所以不是深拷贝 例: let a = { age: 1 }; let b = Object.assign({}, a); a.age = 2; console.log(b.age); // 1 2、展开运算符 ... let a = { age: 1 }; let b = {...a}; a.age = 2; console.log(b.age); // 1 但是浅拷贝只能解决第一层的问题,如果对象下边的值还有对象的话,那么还是会有问题,如果想继续解决就要使用深拷贝了。 问题实例: let a = { age: 1, jobs: { first: 'FE' } } let b = { ...a } a.jobs.first = 'native' console.log(b.jobs.first) // native 深拷贝 深拷贝就是能够实现真正意义上的数组和对象的拷贝。递归调用"浅拷贝"。(深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象) 通常可以通过 JSON.parse(JSON.stringify(object)); 解决 let a = { age: 1, jobs: { first: 'FE' } } let b = JSON.parse(JSON.stringify(a)) a.jobs.first = 'native' console.log(b.jobs.first) // FE 但是这种方法也有局限性 会忽略undefined 会忽略symbol 不能序列化函数 不能解决循环引用的对象 例如 let obj = { a: 1, b: { c: 2, d: 3, }, } obj.c = obj.b obj.e = obj.a obj.b.c = obj.c obj.b.d = obj.b obj.b.e = obj.b.c let newObj = JSON.parse(JSON.stringify(obj)) console.log(newObj) js实现深拷贝具体方法 // 深拷贝 function deepClone(obj, hash = new WeakMap()) { if (obj == null) { return obj; } if (obj instanceof Date) { return new Date(obj); } if (obj instanceof RegExp) { return new RegExp(obj); } if (typeof obj !== 'object') { return obj; } if (hash.has(obj)) { return hash.get(obj); } let cloneObj = new obj.constructor; hash.set(obj, cloneObj); for (let key in obj) { if (obj.hasOwnProperty(key)) { cloneObj[key] = deepClone(obj[key], hash); } } return cloneObj; } 本篇文章只是自己对深浅拷贝的一个简单理解,也参考了一些其他文章 参考文献: https://juejin.im/book/5bdc715fe51d454e755f75ef/section/5bed40d951882545f73004f6 https://www.cnblogs.com/136asdxxl/p/8645750.html

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):