0


深拷贝的五种实现方式

一、什么是深拷贝和浅拷贝

  • 浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是指向内存的地址 ,所以如果其中一个对象改变了这个引用类型的值,就会影响到另一个对象
  • 深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象

二、实现深拷贝的五种方式

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
版权归原作者 前端视野 所有, 如有侵权,请联系我们删除。

“深拷贝的五种实现方式”的评论:

还没有评论