一、什么是深拷贝和浅拷贝
- 浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是指向内存的地址 ,所以如果其中一个对象改变了这个引用类型的值,就会影响到另一个对象。
- 深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。
二、实现深拷贝的五种方式
1、递归调用
// 递归调用constdeepCopy=(obj)=>{// 判断传入的值是否为一个对象if(obj ===null&&typeof obj !=="object"){return obj;}// 判断对象的类型 注意这里不考虑包装类对象if(Object.prototype.toString.call(obj)==="[object Date]"){returnnewDate(obj);}if(Object.prototype.toString.call(obj)==="[object RegExp]"){returnnewRegExp(obj);}if(Object.prototype.toString.call(obj)==="[object Undefined]"){returnnewError(obj);}// 判断对象是类let newObj = Array.isArray(obj)?[]:{}for(let item in obj){if(typeof obj[item]==='object'){
newObj[item]=deepCopy(obj[item])}else{
newObj[item]= obj[item]}}return newObj
};const foo ={name:'张三',info:{age:24}}const newFoo =deepCopy(foo)
console.log(foo, newFoo)
foo.info.age =25
console.log(foo, newFoo)
2、JSON.stringify + JSON.parse
:::info
更多关于JSON.stringigy的注意事项请看MDN
:::
// JSON.stringify// 情况一: 对象内不存在undefined、symbol、function类型的属性时// const foo = {// name: '张三',// info: {// age: 24// }// }// const newFoo = JSON.parse(JSON.stringify(foo))// console.log(foo, newFoo) // { name: '张三', info: { age: 24 } } { name: '张三', info: { age: 24 } }// foo.info.age = 25// console.log(foo, newFoo) // { name: '张三', info: { age: 25 } } { name: '张三', info: { age: 24 } }// 情况二:当对象内存在undefined、symbol、function类型的属性时,在序列化过程中会被忽略。// 当属性为NaN 和 Infinity 格式的数值及 null 都会被当做 nul// const foo = {// name: "张三",// age: undefined,// height: 183,// gender: Symbol("男"), //// say: () => {},// aa: NaN,// };// const newFoo = JSON.parse(JSON.stringify(foo));// console.log(foo, newFoo); // {aa: NaN, age: undefined, gender: Symbol(男), height: 183, name: "张三"} { {name: '张三', height: 183, aa: null} }// JSON.stringify() 第二个参数为可选参数,可以是一个函数或者数组,// 当是数组时表示需要被转化的属性列表,但undeinfed,symbol,function类型的属性依然会被忽略// const newFoo = JSON.parse(JSON.stringify(foo, ['name', 'age', 'gender', 'say', 'aa']));// console.log(newFoo) // {name: '张三', aa: null}
3、lodash
const _ =require('lodash')const foo ={name:'张三',info:{age:24}}const newFoo = _.cloneDeep(foo);
foo.info.age =25
console.log(foo, newFoo)// { name: '张三', info: { age: 25 } } { name: '张三', info: { age: 24 } }
4、Object.assgin
注意:只有当对象中没有嵌套对象时,才可以实现深拷贝
const foo ={name:'张三',age:24}const newFoo = Object.assign({}, foo)
foo.age =25
console.log(foo, newFoo)// {name: '张三', age: 25} {name: '张三', age: 24}// 对象中有内嵌的对象时const foo ={name:'张三',info:{age:24}}const newFoo = Object.assign({}, foo)
foo.info.age =25
console.log(foo, newFoo)// { name: '张三', info: { age: 25 } } { name: '张三', info: { age: 25 } }
5、structuredClone
const foo ={name:'张三',info:{age:24}}const newFoo =structuredClone(foo)//
foo.info.age =25
console.log(foo, newFoo)// { name: '张三', info: { age: 25 } } { name: '张三', info: { age: 24 } }
该方法为Web最新的 API,存在兼容问题
标签:
javascript
前端
本文转载自: https://blog.csdn.net/Z_J_CSDN/article/details/125669594
版权归原作者 前端视野 所有, 如有侵权,请联系我们删除。
版权归原作者 前端视野 所有, 如有侵权,请联系我们删除。