首页 > 其他分享 >最简单的深拷贝和浅拷贝(原理)

最简单的深拷贝和浅拷贝(原理)

时间:2024-02-21 16:47:43浏览次数:33  
标签:stringify name 对象 age JSON 简单 原理 拷贝

拷贝:其实就是一个对象复制给另外一整个对象,让对象相互不影响。

对象的拷贝又分为浅拷贝和深拷贝

对象的浅拷贝:浅拷贝是指只复制对象的第一层属性,如果对象的属性值是引用类型(如对象、数组等),则复制的是引用,而不是真正的拷贝。

对象的深拷贝:深拷贝是指在复制对象时,不仅复制对象本身,还递归地复制对象所有的属性,直到所有属性都是基本数据类型(如字符串、数字、布尔值等),而不是简单地复制对象的引用。这样就可以确保复制后的对象与原始对象完全独立,互不影响。

注意:浅拷贝和深拷贝只针对object和Array这样的复杂的对象

一.浅拷贝Object.assign()

Object.assign() 方法用于将一个或多个源对象的可枚举属性复制到目标对象,并返回目标对象。它实现了浅拷贝的功能。

 

 1 // (1)用来复制一个新对象,并不会影响原对象
 2     let object = {
 3         a : 1
 4     }
 5     let empty = {}
 6     empty = Object.assign(empty,object)
 7     console.log(`object:${JSON.stringify(object)};empty:${JSON.stringify(empty)}`) //object:{"a":1};empty:{"a":1}
 8     
 9     //(2)用来合并对象属性,将源对象的所有可枚举属性,复制到目标对象。
10     let obj = {
11         name : "jack",
12         age : '18'
13     }
14     let obj2 = {
15         work : 'lawyer'
16     }
17     obj2 = Object.assign(obj2,obj)
18     console.log(`obj:${JSON.stringify(obj)};obj2:${JSON.stringify(obj2)}`) //obj:{"name":"jack","age":"18"};obj2:{"work":"lawyer","name":"jack","age":"18"}
19 
20     // (3)如果目标对象和源对象中有相同的键,则属性将被源对象的属性覆盖,后面的源属性会覆盖之前的相同键的源属性。
21     let red ={
22         name : "小红包",
23         age : '20'
24     }
25     let blue = {
26         name : '小兰'
27     }
28     blue = Object.assign(blue,red)
29     console.log(`red:${JSON.stringify(red)};blue:${JSON.stringify(blue)}`)//red:{"name":"小红包","age":"20"};blue:{"name":"小红包","age":"20"}
30     let green = {
31         name : '小吕'
32     }
33     blue = Object.assign(blue,red,green)
34     console.log(`red:${JSON.stringify(red)};blue:${JSON.stringify(blue)};green:${JSON.stringify(green)}`)//red:{"name":"小红包","age":"20"};blue:{"name":"小吕","age":"20"};green:{"name":"小吕"}
35 
36     // (4)当assign只有一个对象时,则直接返回这个对象,不做任何操作;
37     let quondam = {
38         a : 'self'
39     }
40     Object.assign(quondam)
41     console.log(quondam) //{a: 'self'}
42 
43     // (5)Object.assign()方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
44     //当我们在改变person的值时,并没有想改变other,但other的值也发生了改变,这违背了我们的想法。
45     let person = {
46         name : '杨幂',
47         age : '16',
48         works : {
49             video : '宫'  ,
50             musinc : '爱的供养'
51         }
52     }
53     let other = {}
54     other = Object.assign(other,person)
55     console.log(`other:${JSON.stringify(other)}`) //other:{"name":"杨幂","age":"16","works":{"video":"宫","musinc":"爱的供养"}}
56 
57     person.works.video = '三生三世'
58     console.log(`person:${JSON.stringify(person)};other:${JSON.stringify(other)}`)//person:{"name":"杨幂","age":"16","works":{"video":"三生三世","musinc":"爱的供养"}};other:{"name":"杨幂","age":"16","works":{"video":"三生三世","musinc":"爱的供养"}}
59 
60     //(6)给当前的对象添加新的属性
61     const static = {
62         name :'静态对象'
63     }
64     Object.assign(static,{type:'添加属性'})
65     console.log(static) //{name: '静态对象', type: '添加属性'}

 

 

 

Object.assign() 方法的原理如下:

1.首先,创建一个新的空对象作为目标对象。

2.然后,依次遍历源对象的所有可枚举属性,并将这些属性复制到目标对象中。

3.如果源对象的属性值是基本数据类型(如字符串、数字、布尔值等),则直接将其复制到目标对象中。

4.如果源对象的属性值是引用类型(如对象、数组等),则复制的是引用,即目标对象中的属性与源对象中的属性指向同一个引用。

 

总的来说,Object.assign() 方法提供了一种简单且常用的浅拷贝对象的方法,但需要注意引用类型复制的特性以及对属性的覆盖情况。如果需要进行深拷贝,可以使用其他更全面的方法来确保正确性和完整性。

 

二.深拷贝JSON.parse(JSON.stringify())

JSON.parse(JSON.stringify()) 是一种常用的实现深拷贝的方法,它的原理是利用 JSON 的序列化和反序列化过程。

 

 1 let star = {
 2         name :'成毅',
 3         age : '30',
 4         works : {
 5             video : '莲花楼',
 6             music : '江湖之上'
 7         }
 8     }
 9     let lian = { }
10 
11     lian = JSON.parse(JSON.stringify(star))
12     console.log(`star:${JSON.stringify(star)};lian:${JSON.stringify(lian)}`) //star:{"name":"成毅","age":"30","works":{"video":"莲花楼","music":"江湖之上"}};lian:{"name":"成毅","age":"30","works":{"video":"莲花楼","music":"江湖之上"}}
13     star.works.video = '沉香如屑'
14     console.log(`star:${JSON.stringify(star)};lian:${JSON.stringify(lian)}`) //star:{"name":"成毅","age":"30","works":{"video":"沉香如屑","music":"江湖之上"}};lian:{"name":"成毅","age":"30","works":{"video":"莲花楼","music":"江湖之上"}}

 

原理:

1.JSON.stringify():这个方法将一个 JavaScript 对象转换为一个 JSON 字符串。在这个过程中,所有可以被 JSON 格式表示的数据类型(如字符串、数字、布尔值、数组、对象等)都会被正确地转换为对应的 JSON 格式。

2.JSON.parse():这个方法将一个 JSON 字符串解析为一个 JavaScript 对象。在这个过程中,JSON 字符串会被解析为对应的 JavaScript 数据类型。

3.因此,当我们使用 JSON.stringify() 将一个对象进行序列化(转换为 JSON 字符串),然后再使用 JSON.parse() 将该 JSON 字符串进行反序列化(转换为 JavaScript 对象)时,就可以得到原始对象的一个深拷贝

4.需要注意的是,使用 JSON.stringify()JSON.parse() 进行深拷贝的方法有一些限制:只能拷贝能够被 JSON 表示的数据类型,例如函数、正则表达式等无法被正确拷贝;只能拷贝能够被 JSON 表示的数据类型,例如函数、正则表达式等无法被正确拷贝。

 

总的来说,JSON.parse(JSON.stringify()) 方法是一种简单且常用的实现深拷贝的方法,但需要注意上述的限制条件。对于复杂对象或包含特殊数据类型的对象,可能需要使用其他更全面的深拷贝方法来确保正确性和完整性。

 

标签:stringify,name,对象,age,JSON,简单,原理,拷贝
From: https://www.cnblogs.com/qinlinkun/p/18025593

相关文章

  • 模板匹配里的一些数学原理
    模板匹配里的一些数学原理我们知道,在openCV里,模板匹配中匹配度的计算公式有三类。SQDIFF、CCORR、CCOEFF。下面我们来简单介绍一下这三类计算方法,并比较其不同之处。openCV里的模板匹配SQDIFFSQDIFF全称SumofSquaredDifference(SSD),即差的平方和。其离散形式为:\[E(\v......
  • 面试官让我讲讲MySQL三大核心日志实现原理
    本文分享自华为云社区《面试必问|聊聊MySQL三大核心日志的实现原理?》,作者:冰河。MySQL几乎成为互联网行业使用的最多的开源关系型数据库,正因如此,MySQL也成为各大互联网公司面试中必问的数据库,尤其是MySQL中的事务实现机制和三大核心日志的实现原理。今天,我们就重点聊聊MySQL三......
  • dremio FileDatasetHandle 简单说明
    FileDatasetHandle是DatasetHandle的扩展,核心是对于文件系统类的处理(dremio对于文件系统的支持主要是基于hdfs)同时支持对于不同表格式的处理(deltalake,iceber,parquet),单独说明FileDatasetHandle主要是因为此实现比较重要dremio不少文件的处理都和此有关联FileDatasetHandle的一......
  • P5057 [CQOI2006] 简单题
    原题链接题解区间修改+单点查询对于一个点,查询的时候翻转的次数如果是奇数,是1,如果是偶数,是0所以题目转变成对区间上的点加一,然后求单点的奇偶性树状数组对一串序列加1,相当于对其差分序列的\([l]++,[r+1]--\)code#include<bits/stdc++.h>usingnamespacestd;inta[10000......
  • [设计模式]创建型模式-简单工厂模式
    简介简单工厂模式又称为静态工厂模式,属于创建型模式,但不属于GOF23设计模式。由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。简单工厂适用场景:工厂类负责创建的对象比较少;客户端只需要知道传入工厂......
  • 单片机电容式触摸按键原理
    一、前言图1触摸按键应用触摸按键因其外观简洁,科技感强,在电子产品,家电上经常见到。二、触摸按键的原理触摸按键的原理是基于电容感应技术或压力感应技术实现的。以下是这两种技术的原理介绍:1.电容感应技术:触摸按键常见是电容感应式,可以穿透绝缘材料外壳8mm(玻璃、塑料等......
  • LInux下wc命令简单使用
    前言利用wc指令我们可以计算文件的Byte数、字数、或列数,如果不指定文件名称,或者所给予的文件名为"-",则wc指令会从标准输入设备读取数据。使用语法如下wc[-clw][--help][--version][文件...]参数如下-c或--bytes或--chars只显示Bytes数。-l或--lines显示行数。-w或--w......
  • Android 《ViewPagerStrip》简单应用
    布局文件activity_pager_tab_strip.xml<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"......
  • 前端部署真的不简单
    原文地址:https://mp.weixin.qq.com/s/MUP0cAT8FbtE0sRX3ohptw现在大部分的中小型公司部署前端代码都是比较简单的,主要步骤如下:首先,通过脚手架提供的命令npmrunbuild打包前端代码,生成dist文件夹;最后,将dist文件夹丢给后台开发人员放在他们的工程里面,随后台一起部署;现在普遍是......
  • Android 《ViewPager》简单应用
    布局文件<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://sche......