更清晰的认识对象——深拷贝与浅拷贝
栏目: JavaScript · 发布时间: 5年前
内容简介:对象在引用的时候引用的是对象的地址,所以导致如果修改其中一个对象,就会对其他引用这个地址的对象进行修改,这种结果并不是我们想要的,这个时候我们就要用到深拷贝和浅拷贝去解决这个问题了。Object.assign 只会拷贝所有的属性值到新的对象中,如果属性值是对象的话,拷贝的是地址,所以并不是深拷贝。我们可以通过扩展运算符实现浅拷贝。
对象在引用的时候引用的是对象的地址,所以导致如果修改其中一个对象,就会对其他引用这个地址的对象进行修改,这种结果并不是我们想要的,这个时候我们就要用到深拷贝和浅拷贝去解决这个问题了。
var a = { name: 'test' }; var b = a; a.name = 'test1'; console.log(b); // {name: 'test1'} 复制代码
浅拷贝
- Object.assign
Object.assign 只会拷贝所有的属性值到新的对象中,如果属性值是对象的话,拷贝的是地址,所以并不是深拷贝。
var a = { name: 'test' }; var b = Object.assign({}, a); a.name = 'test1'; console.log(b); // {name: 'test'} 复制代码
- ...扩展运算符
我们可以通过扩展运算符实现浅拷贝。
var a = { name: 'test' }; var b = { ...a }; a.name = 'test1'; console.log(b); // {name: 'test'} 复制代码
深拷贝
最简单的深拷贝可以通过 JSON.parse(JSON.stringify(obj))
实现。
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 a = { age: undefined, sex: Symbol('male'), jobs: function() {}, name: 'yck' }; let b = JSON.parse(JSON.stringify(a)); console.log(b); // {name: "yck"} 复制代码
深拷贝我们还可以使用 MessageChannel,这个方法可以处理 undefined 和循环引用对象。
function structuralClone(obj) { return new Promise(resolve => { const { port1, port2 } = new MessageChannel(); port2.onmessage = ev => resolve(ev.data); port1.postMessage(obj); }); } var obj = { a: 1, b: { c: 2 } }; obj.b.d = obj.b; // 注意该方法是异步的 // 可以处理 undefined 和循环引用对象 const test = async () => { const clone = await structuralClone(obj); console.log(clone); }; test(); 复制代码
最简单的我们还可以使用lodash 的深拷贝方法。
如果想自己实现一个深拷贝,其实需要考虑多个边界情况,比较复杂,参考网上的内容,实现一个简易版的深拷贝。
function deepClone(obj) { function isObject(o) { return (typeof o === 'object' || typeof o === 'function') && o !== null; } if (!isObject(obj)) { throw new Error('非对象'); } let isArray = Array.isArray(obj); let newObj = isArray ? [...obj] : { ...obj }; Reflect.ownKeys(newObj).forEach(key => { newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]; }); return newObj; } let obj = { a: [1, 2, 3], b: { c: 2, d: 3 } }; let newObj = deepClone(obj); newObj.b.c = 1; console.log(obj.b.c); // 2 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- JavaScript对象的深拷贝以及浅拷贝分析
- 处理 JavaScript 复杂对象:深拷贝、Immutable & Immer
- JS中解决JSON中函数及对象的深度拷贝
- 在 JavaScript 中对象的深拷贝(及其工作原理)[每日前端夜话0x8F]
- JavaScript深拷贝、浅拷贝
- javaScript浅拷贝、深拷贝
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Netty实战
诺曼·毛瑞尔(Norman Maurer)、马文·艾伦·沃尔夫泰尔(Marvin Allen Wolfthal) / 何品 / 人民邮电出版社 / 2017-5-1 / 69.00
编辑推荐 - Netty之父”Trustin Lee作序推荐 - 阿里巴巴中间件高级技术专家为本书中文版作序推荐 - 系统而详细地介绍了Netty的各个方面并附带了即用型的优质示例 - 附带行业一线公司的案例研究 - 极实用的Netty技术书 无论是构建高性能的Web、游戏服务器、推送系统、RPC框架、消息中间件还是分布式大数据处理引擎,都离不开Nett......一起来看看 《Netty实战》 这本书的介绍吧!