记录--Object.assign 这算是深拷贝吗
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
在JavaScript中,Object.assign() 是一个用于合并对象属性的常见方法。然而,对于许多开发者来说,关于它是否执行深拷贝的认识可能存在一些混淆。先说答案Object.assign() 不属于深拷贝,我们接着往下看。
Object.assign() 概览
首先,让我们回顾一下 Object.assign() 的基本用法。该方法用于将一个或多个源对象的属性复制到目标对象,并返回目标对象。这一过程是浅拷贝的,即对于嵌套对象或数组,只是拷贝了引用而非创建新的对象。
const obj = { a: 1, b: { c: 2 } };
const obj2 = { d: 3 };
const mergedObj = Object.assign({}, obj, obj2);
console.log(mergedObj);
// 输出: { a: 1, b: { c: 2 }, d: 3 }
浅拷贝的陷阱
浅拷贝的特性意味着如果源对象中包含对象或数组,那么它们的引用将被复制到新的对象中。这可能导致问题,尤其是在修改新对象时,原始对象也会受到影响。
const obj = { a: 1, b: { c: 2 } };
const clonedObj = Object.assign({}, obj);
clonedObj.b.c = 3;
console.log(obj); // { a: 1, b: { c: 3 } }
console.log(clonedObj); // { a: 1, b: { c: 3 } }
在这个例子中,修改 clonedObj 的属性也会影响到原始对象 obj。
因此,如果我们需要创建一个全新且独立于原始对象的拷贝,我们就需要进行深拷贝。而 Object.assign() 并不提供深拷贝的功能。
深拷贝的需求
如果你需要进行深拷贝而不仅仅是浅拷贝,就需要使用其他的方法,如使用递归或第三方库来实现深度复制。以下是几种常见的深拷贝方法:
1. 使用 JSON 序列化和反序列化
const obj = { a: 1, b: { c: 2 } };
const deepClonedObj = JSON.parse(JSON.stringify(obj));
deepClonedObj.b.c = 3;
console.log(obj); // { a: 1, b: { c: 2 } }
console.log(deepClonedObj); // { a: 1, b: { c: 3 } }
这种方法利用了 JSON 的序列化和反序列化过程,通过将对象转换为字符串,然后再将字符串转换回对象,实现了一个全新的深拷贝对象。
需要注意的是,这种方法有一些限制,例如无法处理包含循环引用的对象,以及一些特殊对象(如 RegExp 对象)可能在序列化和反序列化过程中失去信息。
2. 使用递归实现深拷贝
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
const clonedObj = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clonedObj[key] = deepClone(obj[key]);
}
}
return clonedObj;
}
const obj = { a: 1, b: { c: 2 } };
const deepClonedObj = deepClone(obj);
deepClonedObj.b.c = 3;
console.log(obj); // { a: 1, b: { c: 2 } }
console.log(deepClonedObj); // { a: 1, b: { c: 3 } }
这是一个递归实现深拷贝的方法。它会递归地遍历对象的属性,并创建它们的副本。这种方法相对灵活,可以处理各种情况。
但需要注意在处理大型对象或深度嵌套的对象时可能会导致栈溢出。
3. 使用第三方库
许多第三方库提供了强大而灵活的深拷贝功能,其中最常用的是 lodash 库中的 _.cloneDeep 方法。
const _ = require('lodash');
const obj = { a: 1, b: { c: 2 } };
const deepClonedObj = _.cloneDeep(obj);
deepClonedObj.b.c = 3;
console.log(obj); // { a: 1, b: { c: 2 } }
console.log(deepClonedObj); // { a: 1, b: { c: 3 } }
使用第三方库的优势在于它们通常经过精心设计和测试,可以处理更多的边界情况,并提供更好的性能。
本文转载于:
https://juejin.cn/post/7325040809697591296
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--Object.assign 这算是深拷贝吗的更多相关文章
- Object.assign()的使用
一.Object.assign()对象的拷贝 1 Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象.它将返回目标对象. 2 Object.assign(ta ...
- js - object.assign 以及浅、深拷贝
浅(引用)拷贝:共用同一内存地址,你改值我也变 譬如常用的对象赋值操作 深拷贝:深拷贝即创建新的内存地址保存值(互不影响) 譬如以下 const shallBasicCopy = obj => ...
- Object.assign()与深拷贝(一)
深拷贝与浅拷贝 所谓深拷贝与浅拷贝,是围绕引用类型变量的拷贝进行的讨论. 在ECMAScript中,变量分为基本类型和引用类型两种.其本质区别是不可变性,基本类型是不可变的,而引用类型是可变的. 所谓 ...
- javascript学习总结之Object.assign()方法详解
最近再写ES6的文章时候发现自己对Object.assign()方法不太了解,之前也没有接触过所以就就查阅了相关的资料,为了自己以后肯能会用到以及对知识进行巩固,所以在这里记录下自己学习的点点滴滴,毕 ...
- Object.assign()方法
对象的扩展 1.ES6中,对象的属性和方法可简写:对象的属性值可不写,前提是属性名已经声明: var name = "zhangsan"; "; var obj = { ...
- es6 Object.assign
ES6 Object.assign 一.基本用法 Object.assign方法用来将源对象(source)的所有可枚举属性,复制到目标对象(target).它至少需要两个对象作为参数,第一个参数是目 ...
- 浅谈Object.assign()
Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象.返回值为目标对象. 1 Object.assign 是 ES6 新添加的接口,主要的用途是用来合并多个 Ja ...
- vue android低版本 白屏问题 你是不是用了Object.assign ??
问题描述 在部分比较低版本的手机中,发现apk安装后白屏,但是大部分手机都能安装. 本人在使用android4.4时候,也是安装后打开白屏. 原因: 代码写法不兼容 this.user = Objec ...
- Object.assign 的问题
功能及问题 如下代码, 使用用户最后一次配置信息的同时,当用户关闭数据记录时提示用户确定关闭. export default { name: 'editPage', data() { return { ...
- Object.assign()解释整理
链接:https://blog.csdn.net/wang252949/article/details/79106160 语法 Object.assign(target, ...sources) 参数 ...
随机推荐
- NC24158 [USACO 2015 Jan G]Moovie Mooving
题目链接 题目 题目描述 Bessie is out at the movies. Being mischievous as always, she has decided to hide from ...
- STM32F401的PWM输出
PWM的说明 PWM有三个关键指标: PWM频率, 占空比, 区分度 对于同一个时钟频率下工作的单片机, 区分度是和PWM工作频率相关的, 因为总频率是固定的, PWM工作频率越高, 留下给区分度的部 ...
- 【Android】使用MediaExtractor获取关键帧的时间戳
1 前言 使用MediaExtractor.MediaMuxer去掉视频文件中的音频数据 中介绍了 MediaExtractor 类的主要方法,本文主要将使用其 advance() 和 seekTo( ...
- GYM-A. Golden Spirit等
1.题目链接:Problem - A - Codeforces 题意:桥两边有2 * n个不能独立过桥的老人,老人想到对面休息 re 分钟后返回原位置,每次过桥需要花费 cr 分钟,问最少需要多长时间 ...
- Go微服务框架go-kratos实战学习08:负载均衡基本使用
微服务框架 go-kratos 中负载均衡使用 一.介绍 在前面这篇文章 负载均衡和它的算法介绍,讲了什么是负载均衡以及作用.算法介绍. go-kratos 的负载均衡主要接口是 Selector,它 ...
- 负载均衡load balancing和算法分类概要介绍
一.负载均衡介绍 1.1 什么是负载均衡 负载均衡(load balancing) 它是计算机的一种技术,用来在计算机集群.网络连接.CPU.磁盘驱动器或其他资源中分配负载,以达到优化资源使用.最大化 ...
- 异常处理之raise A from B
raise A from B 语句用于连锁chain异常 from 后面的B可以是: - 异常类 - 异常实例 - None 如果B是异常类或者异常实例,那么B会被设置为A的__cause__属性,表 ...
- Oracle触发器联合唯一约束
Oracle支持可为空字端的唯一约束呢?下面就是用触发器作出的限制语句,仅供参考: CREATE OR REPLACE TRIGGER Tg_Completion_Test BEFORE INSERT ...
- 【Azure Data Lake Storage】如何才能保留Blob中的文件目录结构(即使文件夹中文件数量为0的情况下)?
问题描述 在使用Azure Storage Account Blob时候,发现当文件夹中的Blob(文件)被全部输出后,文件夹也会消失? 为什么它不能像Windows系统中的文件夹一样,即使是一个空文 ...
- 【Azure Cloud Service】Cloud Service(Classic) 迁移失败,找不到解决方案怎么办?
问题描述 很老很老的云服务,在迁移到 Cloud Service(Extended Support)[云服务外延支持] 时,迁移的验证步骤不通过,因为资源中没有包含虚拟网络(Virtual Netwo ...
