·

Vue浅拷贝和深拷贝

发布时间:2024-08-29 16:10:37阅读量:202
专业文章
转载请注明来源

前言

在理解浅拷贝和深拷贝浅前,必须先理解基本数据类型和引用数据类型的区别。

一、数据类型

1.1.基本数据类型

字符串(Sring)、布尔值(Boolean)和数字(Number)

1.2.引用数据类型

数组(Array)和对象(Object)

1.3.区别

基本数据类型是存储在栈内存中。而引用类型存放的值是指向数据的引用,而不是数据本身,真实数据是存放在堆内存里,具体见如下:

二、浅拷贝

2.1. 定义

浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。即默认拷贝构造函数只是对对象进行浅拷贝复制(逐个成员依次拷贝),即只复制对象空间而不复制资源。

2.2. 浅拷贝特点

对于基本数据类型的成员对象,因为基础数据类型是值传递的,所以是直接将属性值赋值给新的对象。基础类型的拷贝,其中一个对象修改该值,不会影响另外一个。

var a = 10
var b = a
b = 20
console.log("a",a) //10
console.log("b",b) //20

对于引用类型,比如数组或者类对象,因为引用类型是引用传递,所以浅拷贝只是把内存地址赋值给了成员变量,它们指向了同一内存空间。改变其中一个,会对另外一个也产生影响

var obj = {
    a:"AAA"
}
var obj2 = obj
obj2.a = "BBB"
console.log("obj",obj) //{name: "BBB"}
console.log("obj2",obj2) //{name: "BBB"}

三、深拷贝

3.1. 定义

深拷贝,在拷贝引用类型成员变量时,为引用类型的数据成员另辟了一个独立的内存空间,实现真正内容上的拷贝。

3.2. 深拷贝特点

对于基本数据类型的成员对象,因为基础数据类型是值传递的,所以是直接将属性值赋值给新的对象。基础类型的拷贝,其中一个对象修改该值,不会影响另外一个(和浅拷贝一样)。

对于引用类型,比如数组或者类对象,深拷贝会新建一个对象空间,然后拷贝里面的内容,所以它们指向了不同的内存空间。改变其中一个,不会对另外一个也产生影响。

var obj = {
    a:"AAA"
}
var obj2 = {} // 创建新的对象
obj2 = obj
obj2.a = "BBB"
console.log("obj",obj) //{name: "AAA"}
console.log("obj2",obj2) //{name: "BBB"}

四、拷贝实现方案

4.1. Object.assign()

单级结构时深拷贝,多级结构浅拷贝,Object.assign()对象是用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,将返回目标对象。

a)单级结构(一级拷贝是深拷贝):

var obj = {
    a: 10,
}
var obj2 = Object.assign({}, obj);
obj2.a = 20
console.log("obj",obj); //{a: 10}
console.log("obj2",obj2) //{a: 20}

b)多级结构(一级拷贝是浅拷贝,修改二级对象还是会影响原对象):

var obj = {
    a: 10,
    b: {
        c:"AAA",
        d:666
    }
}
var obj2 = Object.assign({}, obj);
obj2.b.c = "BBB"
console.log("obj",obj); //{a: 10,b: {c:"BBB",d:666}}
console.log("obj2",obj2); //{a: 10,b: {c:"BBB",d:666}}

4.2. concat()

单级结构时深拷贝,多级结构浅拷贝

a)单级结构(一级拷贝是深拷贝):

let arr = [1, 2];
let arr2 = arr.concat();
arr2[1] = 3;
console.log("arr",arr) //[1, 2]
console.log("arr2",arr2) //[1, 3]

b)多级结构(一级拷贝是浅拷贝):

let arr = [1, 2, {
    a: 'AAA'
}];
let arr2 = arr.concat();
arr2[2].a = 'BBB';
console.log("arr",arr) //[1, 2, {a: 'BBB'}]
console.log("arr2",arr2) //[1, 2, {a: 'BBB'}]

4.3. slice()

单级结构时深拷贝,多级结构浅拷贝

a)单级结构(一级拷贝是深拷贝):

let arr = [1, 2, 3];
let arr2 = arr.slice();
arr2[1] = 4;
console.log("arr",arr) //[1, 2, 3]
console.log("arr2",arr2) //[1, 4, 3]

b)多级结构(一级拷贝是浅拷贝):

let arr = [1, 2, {a:'AAA'}];
let arr2 = arr.slice();
arr2[2].a = 'BBB';
console.log("arr",arr) //[1, 2, {a: 'BBB'}]
console.log("arr2",arr2) //[1, 2, {a: 'BBB'}]

4.4.JSON.parse(JSON.stringify())

用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。

单级多级均为深拷贝,但需要注意无法拷贝RegExp对象、function和symbol

let arr = [1, 2, {a:'AAA'}];
let arr2 = JSON.parse(JSON.stringify(arr))
arr2[2].a = 'BBB';
console.log("arr",arr) //[1, 2, {a: 'AAA'}]
console.log("arr2",arr2) //[1, 2, {a: 'BBB'}]

4.5. cloneDeep()

单级多级均为深拷贝,使用lodash工具中cloneDeep方法实现深拷贝,需要通过npm引入lodash库

npm i -save lodash //全局安装
<script>
  import _ from 'lodash';

  export default {
    name: 'Test',
    mounted() {
      const arr = [1, 2, { a: 'AAA' }];
      const arr2 = _.cloneDeep(arr);
      arr2[2].a = 'BBB';
      console.log('arr', arr); // [1, 2, {a: 'AAA'}]
      console.log('arr2', arr2); // [1, 2, {a: 'BBB'}]
    },
  };
</script>

五、结论

类型第一级为基础数据类型原数据中包含子对象
浅拷贝改变不会使原始数据改变改变会使原始数据改变
深拷贝改变不会使原始数据改变改变不会使原始数据改变


原文链接:https://blog.csdn.net/ltlt654321/article/details/127047262

0 人喜欢

评论区

暂无评论,来发布第一条评论吧!

弦圈热门内容

为什么可能没有体积的量子所组成的物质却有体积?

当你测量和观察周围的宇宙时,有一件事是可以肯定的:你看到、触摸到并以其他方式与之互动的物理对象都占据了一定的空间体积。无论是固体、液体、气体还是物质的任何其他形态,它都需要消耗能量来减少任何有形物质所占的体积。然而,看似矛盾的是,作为物质的基本成分,标准模型的粒子却根本没有可测量的体积;它们只是点粒子。那么,由无体积实体组成的物质如何占据空间,创造出我们所观察到的世界和宇宙呢?让我们从我们熟悉的事物开始,一步步分解,直到我们深入到支撑我们存在的量子规则。最后,我们可以从那里开始逐步向上。上图显示了对应于电磁波谱各个部分的尺寸、波长和温度/能量尺度。你必须使用更高的能量和更短的波长来探测最小的尺度。紫外线足以使原子电离,但随着宇宙的膨胀,光会系统地转移到更低的温度和更长的波长。如果你想了解体积,那么你必须了解我们测量物体大小的方式。确定宏观实体大小的方式通常是将其与已知大小的参考标准进行比较,例如尺子或其他测量棒。或者测量弹簧(或类似弹簧的物体)因该物体而位移的力、测量光穿过物体跨度所需的传播时间,甚至通过用特定波长的粒子或光子撞击物体的实验反馈来进行确定。正如光具有由其能量定义的量子力 ...

波尔兹曼大脑:宇宙中漂浮着至少7万5千亿亿亿个意识体

在这个广袤无垠的宇宙中,我们总爱幻想自己独一无二,是万物之灵。但你知道吗?根据某个奇妙的科学理论,你、我,甚至整个地球,可能都只是宇宙中随机“涨落”出来的一个意识体——没错,这就是让人脑洞大开的“玻尔兹曼大脑”假说!熵增定律:宇宙为何越来越“乱”?你的房间如果不打扫,是不是会越来越乱?这就是“熵增定律”在生活中的体现。简单来说,熵就是系统混乱程度的量度,而熵增定律则告诉我们,一个孤立系统的熵总是趋向于增加,直到达到最大化,也就是系统变得最混乱。宇宙,作为一个巨大的孤立系统,按理说也应该遵循这一法则。但奇怪的是,我们观测到的宇宙,似乎是从一个极其有序、熵极低的状态开始的。这,是为什么呢?玻尔兹曼的“脑洞”:宇宙其实是个“随机播放器”?这时,奥地利物理学家路德维希·玻尔兹曼登场了。他提出,熵增定律其实是统计性的,就像抛硬币,虽然正面朝上的概率是50%,但在无限次抛掷中,正面和反面出现的次数会趋于相等。同样,宇宙在大部分时间处于高熵态,但无限的时间尺度上,偶尔也会有“小概率事件”发生,即熵的随机涨落导致低熵态的出现。换句话说,我们现在所看到的这个有序、低熵的宇宙,可能只是一次“宇宙级”的随机 ...

Jürgen Jost黎曼几何与几何分析教材:Riemannian Geometry and Geometric Analysis

这本书是几何分析方面的入门教材,该教材先从最基本的黎曼流形讲起,然后逐步深入到李群和向量丛,接着到联络与曲率,基本上覆盖了几何分析很多重要的基础概念。这本书需要有一定的微分几何基础以及分析、李群等相关领域的基础,初学者谨慎使用。我高中的时候,就是对这本书的内容感兴趣,想要尝试理解,结果看到测地线就不懂了,接着后面看了点李群和向量丛就没再看了。建议先读Loring W Tu的两本微分几何教材Loring W Tu微分几何经典入门教材:An Introduction to Manifolds和Loring W Tu微分几何教材:Differential Geometry Connections, Curvature, and Characteristic Classes,有了一定的基础再专研Jürgen Jost的这本教材。我毕竟不是做微分几何的,所以关于这方面的就不说太多了。PS:作者不再提供附件下载。

Loring W Tu微分几何教材:Differential Geometry Connections, Curvature, and Characteristic Classes

在上帖Loring W Tu微分几何经典入门教材:An Introduction to Manifolds中,我提到高中时期,我为了看懂Jürgen Jost的几何分析教材Riemannian Geometry and Analysis,转而看Loring W Tu的An Introduction to Manifolds以及Differential Geometry Connections, Curvature, and Characteristic Classes。这本教材可以说是An Introduction to Manifolds的后续,建议先看一下An Introduction to Manifolds有了流形的基础,再看这本Connections, Curvature, and Characteristic Classes。本书开始就直接先从黎曼流形开始讲起,接着就讲曲率、联络这些微分几何进阶的重要基本概念。这也是为什么当初我会选择看这本书,因为这些内容刚好有助于我理解Riemannian Geometry and Analysis这本教材的内容(记得当时看到测地线就看不 ...

素数在整数整环中还是素的吗?

我的提问:一个整环$R$中的元素$p$是素的,如果$p$不是零或者一个单元,并且$p|ab$意味着$p|a$或者$p|b$(等价的$ab\in Rp$意味着$a \in Rp$或者$b\in Rp$)。一个整环$R$的元素$q$是不可约的,当$q$不是零或者一个单元,并且$q = ab$意味着$a$或$b$是一个单元。那么素数在整数整环中是素的吗?然后素数都是不可约的吗?回答1:这两个问题的都是对的。根据基础数论的事实,$\pm 1$是唯一可逆的整数,除$\pm 1$以外的整数可以唯一地表示为不同素数的乘积加上$\pm$,每个素数的幂都是正整数,这两个结果都很容易得到。回答2:素数在整数整环中既是素的,也是不可约的。根据定义,它们就是不可约的。为了证明它们是素的,请回顾一下欧几里得算法,该算法用于找到两个整数的GCD(并同时证明任意两个整数都有一个在等价意义下唯一的GCD,其中并不涉及素数的分解)。根据欧几里德算法可以得出,如果$d=\gcd(a,b)$对两个整数$a,b\in\mathbb Z$,则存在整数$u,v\in\mathbb Z$使得$d=ua+vb$。(贝祖特性。)现在, ...

2024-11-22凌晨:弦圈最近两周更新情况

在上篇弦圈11月10日上下更新计划:小金库、打赏等功能,我提到会更新网站多个功能。原本以为这些功能最多一周就能全部写完,结果当我真正开始写,才发现自己完全低估了这些功能实现的难度,以及所需要耗费的时间。而且由于我的完美主义倾向,导致我比原计划多开发了好几个功能,比如说编辑器插入公式、交易中心、收藏党最喜爱的收藏夹等。因为我想反正都大更新了,那干脆就更新得多一些,把以前埋的坑都填上。再然后支付功能比我想象中的要难得多,这不仅仅指代码难写,还包括支付宝的审核等问题,人事问题上也耗费了不少时间。在这里忍不住吐槽一下支付宝和微信支付,这国内两家巨头技术文档写的是真烂、真水。多少年了,支付宝支付SDK的demo示例还是Java、PHP,Python压根没写,只能自己摸索然后网上找到些零散的资料。微信支付先是需要微信认证强制每年收费300元,然后文档也是写得不清不楚。反正目前网站就暂时只支持支付宝吧,之后再把微信支付补上吧,因为真的被恶心到了。总之如今写了快两个星期了,这些功能终于要完成了,预计明后天就能上线测试。网站也完全没更新,也找不到人帮忙更新,只能先放着了。之后我会发一篇更新日志,更加详细 ...

弦圈11月10日上下更新计划:小金库、打赏等功能

这几天忙于写代码完善网站功能,不太有空更新文章和内容。因为弦圈没有借助任何建站工具和博客框架,是我自己前后端一起从零开始写的,因此开发得会比较慢,请谅解。。。目前计划上线功能首先就包括,前面弦圈更新日志:关于智力值和金币提到的小金库。获取金币的机制是:智力值存入银行(叫时空银行time bank?),然后根据日利率每天产生相应的金币。下图为测试画面其次为了让网站能够更好的运作下去,从而给大家提供更好的服务,我计划引入盈利功能。所谓盈利功能即是用户通过弦圈来获得收益的相关功能,包括打赏功能、接广告功能、接悬赏功能。这些功能主要是为了鼓励大家为社区做贡献,并且让需要得到帮助的人更容易获得帮助(毕竟大佬们忙得很,不会轻易帮助你解决问题)。具体规则暂定如下:想要让弦圈的用户能赚钱,那弦圈必须自己先能赚到钱,目前我计划引入弦圈广告和用户交易中心。至于弦圈广告,我打算采用信息流广告、侧边栏广告、文章内嵌广告,拒绝弹窗之类遮蔽视线的广告,因此不会影响用户体验。最后我还得把之前留的坑——创作中心给填上,就是一个给创作者的方便管理内容、查看数据的模块。测试画面如下:尽情期待😇

Grothendieck经典著作:代数几何原理EGA 1(1971第二版)法语+英译

在前面几贴中,我已经分别分享了Grothendieck的代数几何三部曲EGA、SGA、FGA,链接如下:代数几何教皇Grothendieck经典著作:代数几何原理EGA法语原版全系列(1)代数几何教皇Grothendieck经典著作:代数几何讨论班SGA法语原版全系列代数几何教皇Grothendieck经典著作:代数几何基础FGA法语原版+英文译版但其实EGA 1还有1971年的第二版,Grothendieck在EGA 1第二版中更新了一些内容,因此一些概念定义会与第一版中有出入。原本我也是不太知道EGA竟然还会有第二版,直到后来有次看文献时,发现作者引用了EGA 1(1971)才知道有这一版本。对比EGA 1第一版跟第二版,感觉第二版要比第一版更好读一些,似乎思路行文更清晰,也更好理解。并且值得开心的是,EGA 1第二版有完整英译,现在我全都分享出来。更新:作者不再提供文件下载。