前端 | 浅拷贝深拷贝

server/2025/2/6 0:17:30/

前端开发中,我们经常需要复制对象或数组,但不同的复制方式可能会影响数据的完整性和应用的稳定性。本文将深入探讨浅拷贝(Shallow Copy)和深拷贝(Deep Copy)的区别、实现方式及适用场景。

1. 浅拷贝

1.1 什么是浅拷贝

浅拷贝指的是仅复制对象的第一层属性,而不会复制嵌套对象的引用。如果原对象的某个属性是引用类型(如对象或数组),浅拷贝后,拷贝对象的该属性仍然指向原对象中的引用地址,修改拷贝对象的嵌套属性会影响原对象。

1.2 浅拷贝的实现方式
1)Object.assign()

Object.assign()是ES6中对象的拷贝方法,接受的第一个参数是目标对象,其余参数是源对象,用法:Object.assign(target, source_1, ···),该方法可以实现浅拷贝,也可以实现一维对象的深拷贝。

let target = {a: 1};
let object2 = {b: 2};
let object3 = {c: 3};
Object.assign(target,object2,object3);  
console.log(target);  // {a: 1, b: 2, c: 3}
2)扩展运算符

使用扩展运算符可以在构造字面量对象的时候,进行属性的拷贝。语法:let cloneObj = { ...obj };

let obj1 = {a:1,b:{c:1}}
let obj2 = {...obj1};
obj1.a = 2;
console.log(obj1); //{a:2,b:{c:1}}
console.log(obj2); //{a:1,b:{c:1}}
obj1.b.c = 2;
console.log(obj1); //{a:2,b:{c:2}}
console.log(obj2); //{a:1,b:{c:2}}
3)数组方法实现数组浅拷贝

Array.prototype.slice

  • slice()方法是JavaScript数组的一个方法,这个方法可以从已有数组中返回选定的元素:用法:​array.slice(start, end)​,该方法不会改变原始数组。
  • 该方法有两个参数,两个参数都可选,如果两个参数都不写,就可以实现一个数组的浅拷贝。
let arr = [1,2,3,4];
console.log(arr.slice()); // [1,2,3,4]
console.log(arr.slice() === arr); //false

Array.prototype.concat

  • concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
  • 该方法有两个参数,两个参数都可选,如果两个参数都不写,就可以实现一个数组的浅拷贝。
let arr = [1,2,3,4];
console.log(arr.concat()); // [1,2,3,4]
console.log(arr.concat() === arr); //false
4)手写实现浅拷贝
function shallowCopy(object) {if (!object || typeof object !== "object") return;  // 只拷贝对象// 根据 object 的类型判断是新建一个数组还是对象let newObject = Array.isArray(object) ? [] : {};// 遍历 object,并且判断是 object 的属性才拷贝for (let key in object) {if (object.hasOwnProperty(key)) {newObject[key] = object[key];}}return newObject;
}

2. 深拷贝

2.1 什么是深拷贝?

深拷贝指的是创建一个完全独立的副本,拷贝后的对象与原对象互不影响。如果原对象包含嵌套对象,深拷贝会递归复制所有层级的内容,而不是复制引用。

2.2 深拷贝的实现方式
1)JSON方法
  • JSON.parse(JSON.stringify(obj))是目前比较常用的深拷贝方法之一,它的原理就是利用 JSON.stringify 将 js对象序列化(JSON字符串),再使用 JSON.parse来反序列化(还原)js对象。
  • 这个方法可以简单粗暴的实现深拷贝,但是还存在问题,拷贝的对象中如果有函数,undefined,symbol,当使用过 JSON.stringify()进行处理之后,都会消失。
let obj1 = {  a: 0,b: {c: 0}};
let obj2 = JSON.parse(JSON.stringify(obj1));
obj1.a = 1;
obj1.b.c = 1;
console.log(obj1); // {a: 1, b: {c: 1}}
console.log(obj2); // {a: 0, b: {c: 0}}
2)手写实现深拷贝
// 深拷贝的实现
function deepCopy(object) {if (!object || typeof object !== "object") return;let newObject = Array.isArray(object) ? [] : {};for (let key in object) {if (object.hasOwnProperty(key)) {newObject[key] =typeof object[key] === "object" ? deepCopy(object[key]) : object[key];}}return newObject;
}

3. 浅拷贝 vs 深拷贝

特点适用场景
浅拷贝仅复制第一层,引用类型仍然共享适用于对象层级较浅、且不担心数据共享的情况
深拷贝递归复制所有属性,生成全新对象适用于数据完全独立、对象层级较深的情况

http://www.ppmy.cn/server/165274.html

相关文章

Spring Boot常用注解深度解析:从入门到精通

今天,这篇文章带你将深入理解Spring Boot中30常用注解,通过代码示例和关系图,帮助你彻底掌握Spring核心注解的使用场景和内在联系。 一、启动类与核心注解 1.1 SpringBootApplication 组合注解: SpringBootApplication Confi…

Workbench 中的热源仿真

探索使用自定义工具对移动热源进行建模及其在不同行业中的应用。 了解热源动力学 对移动热源进行建模为各种工业过程和应用提供了有价值的见解。激光加热和材料加工使用许多激光束来加热、焊接或切割材料。尽管在某些情况下,热源 (q) 不是通…

DeepSeek的崛起与全球科技市场的震荡

引言 近年来,人工智能(AI)技术的快速发展不断重塑全球科技格局。 近日,中国初创企业DeepSeek推出了一款据称成本极低且性能强大的AI模型,引发全球市场的剧烈反应。NVIDIA、台积电等半导体和AI科技巨头股价大幅下跌&am…

两栏布局、三栏布局、水平垂直居中

文章目录 1 两栏布局1.1 浮动 margin1.2 浮动 BFC1.3 flex布局1.4 左绝父相 margin1.5 右绝父相 方向定位 2 三栏布局2.1 子绝父相 margin2.2 flex布局2.3 浮动 margin2.4 圣杯布局2.5 双飞翼布局 3 水平垂直居中3.1 绝对定位 translate3.2 绝对定位 margin3.3 绝对定位…

Android-音频采集

前言 音视频这块,首先是要先采集音频。今天我们就来深入探讨一下 Android 音频采集的两大类型:Mic 音频采集和系统音频采集。 Mic音频采集 Android提供了两个API用于实现录音功能:android.media.AudioRecord、android.media.MediaRecorder。…

从Transformer到世界模型:AGI核心架构演进

文章目录 引言:架构革命推动AGI进化一、Transformer:重新定义序列建模1.1 注意力机制的革命性突破1.2 从NLP到跨模态演进1.3 规模扩展的黄金定律二、通向世界模型的关键跃迁2.1 从语言模型到认知架构2.2 世界模型的核心特征2.3 混合架构的突破三、构建世界模型的技术路径3.1 …

Flink报错Caused by: java.io.FileNotFoundException: /home/wc.txt

当在提交一个flink任务报如下的错误时: Caused by: java.io.FileNotFoundException: /home/wc.txt (没有那个文件或目录)at java.io.FileInputStream.open0(Native Method)at java.io.FileInputStream.open(FileInputStream.java:195)at java.io.FileInputStream.&…

Python-基于PyQt5,wordcloud,pillow,numpy,os,sys的智能词云生成器

前言:日常生活中,我们有时后就会遇见这样的情形:我们需要将给定的数据进行可视化处理,同时保证呈现比较良好的量化效果。这时候我们可能就会用到词云图。词云图(Word cloud)又称文字云,是一种文…