深拷贝的五种实现方式
一、什么是深拷贝和浅拷贝
- 浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是指向内存的地址 ,所以如果其中一个对象改变了这个引用类型的值,就会影响到另一个对象。
- 深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。
二、实现深拷贝的五种方式
1、递归调用
// 递归调用
const deepCopy = (obj) => {
// 判断传入的值是否为一个对象
if (obj === null && typeof obj !== "object") {
return obj;
}
// 判断对象的类型 注意这里不考虑包装类对象
if (Object.prototype.toString.call(obj) === "[object Date]") {
return new Date(obj);
}
if (Object.prototype.toString.call(obj) === "[object RegExp]") {
return new RegExp(obj);
}
if (Object.prototype.toString.call(obj) === "[object Undefined]") {
return new Error(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,存在兼容问题
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfchaf
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01