·

Vue浅拷贝和深拷贝

发布时间:2024-08-29 16:10:37阅读量:236
转载请注明来源

前言

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

一、数据类型

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 人喜欢

评论区

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

弦圈热门内容

克服外部环境相关性局限的船舶运动预测——相关性分析阶段

引言伴随全球航运贸易的持续增长,船舶航行安全已成为业界日益关注的核心议题。海上船舶的姿态受多重环境因素综合作用,如海浪和风力的动态影响,其运动状态呈现复杂多变性。船舶的运动姿态通常通过六个自由度来精确刻画,包括艏摇、横摇、纵摇、垂荡、横荡及纵荡【李荣宗,张超群.基于长短期记忆模型的船舶横摇运动预测】。在这六个自由度中,横摇运动因其对航行安全构成的潜在威胁最为显著而备受重视。特别是在遭遇纵向波浪时,船舶极易产生大幅度横摇,且其运动特性往往表现出显著的非线性和固有的难以预测性。这种剧烈的横向摇晃可能在短时间内迅速加剧,甚至诱发危险的参数横摇现象,导致其幅度和频率的异常波动,从而极大地增加船舶倾覆或失稳的风险。鉴于船舶横摇运动的复杂性及其对航行安全的深远影响,准确获取并理解船舶实时姿态数据及其与外部环境,特别是与海浪特征之间的耦合关系显得尤为关键。传统的船载传感器虽能提供船舶姿态信息,但其与诱发横摇的主导因素——海浪之间的直接关联性分析仍有待深入。在此背景下,本研究首先探索船舶姿态运动数据与环境波浪雷达数据之间的内在相关性,通过对这两种异构数据源进行融合与深入分析,我们期望能够揭示海浪要素( ...

小众开源工具分享——5分钟上手视频压缩神器:HandBrake

https://soft.kafan58.com/soft/261375.html ‌HandBrake 是一款跨平台开源视频转码软件‌,支持 Windows、Mac 和 Linux 系统,主要用于视频格式转换、压缩处理及多轨道音视频编码,最新版本为 v1.9.2(截至 2025 年)。‌核心功能与特点‌:‌多格式支持‌: 输入源:支持 DVD、蓝光、AVI、MKV、MP4、MOV 等常见格式。‌‌输出格式:MP4、MKV、WebM 等主流容器格式,兼容各类设备和播放器。‌‌高效编码与压缩‌: 集成 x264、H.265(HEVC)、VP9 等视频编码器,支持恒定质量(CRF)与平均码率(CBR)控制。‌‌可通过调整分辨率、帧率、比特率等参数压缩视频大小。‌‌高级功能‌: 批量转换、字幕嵌入、音轨选择、章节标记及视频滤镜(如裁切、旋转)。‌‌支持加密 DVD 处理和多任务并行转换。‌‌‌适用场景‌:‌格式转换‌:将不兼容的视频转换为 MP4/MKV 等通用格式。‌‌压缩优化‌:减少文件体积以节省存储或传输时间。‌‌专业编辑‌:自定义分辨率、帧率、字幕等参数,满足多样化需求。‌‌

6月10号 欧洲之旅最后一站:荷兰纳尔登

【🇳🇱6.10 纳尔登】 ​欧洲旅游最后一站,居留卡马上就到期了[裂开]特地来阿姆斯特丹附近观摩一下整个城镇都是棱堡的星型要塞城镇纳尔登。和阿维拉的城墙一样,纳尔登的棱堡结构也保存得非常完好,可以明确看到三角堡,幕墙,斜堤等。而且也是亲眼见到荷兰棱堡特有的与荷兰水线防御体系相结合的壕沟护城河设计。如今原有保存完好的堡垒已经彻底民用化,被用作健身房,餐厅,画室等。小镇几乎没有游客,甚至连本地人也寥寥无几,停满车的街道上空无一人,除了一座博物馆外几乎没有任何旅游业的痕迹(甚至博物馆的售票员老奶奶还特意给了我半票)。也就只有在没被商业化的街道上才能看到所谓古镇古城最真实的面貌了

6月6号-6月7号 荷兰鹿特丹

【🇳🇱6.6-6.7 鹿特丹】 ​突破模式-鹿特丹 ​大 获 全 胜 ​战地V鹿特丹地图圣地巡礼,又是一个我有好多好兄弟似在这里的地方()p3《我是谁》里面的成龙快乐楼()也是一个圣地巡礼,是的主要任务就是圣地巡礼来了 ​鹿特丹也让我有很强的回国的感觉,主要整体感觉非常现代(毕竟古建筑大部分都炸没了),看起来和国内大都市一样,但是没有国内的快节奏,不只是方块屋铅笔屋等标志性的景点,大部分建筑感觉都很有设计感却不违和 ​小孩堤防风车群不说了,太,美,了😭走在空无一人两边都是芦苇风车的小路上,远处是在吃草的奶牛和成排的野雁,密密麻麻的小雨铺面而来,再次感受到了在瑞士劳特布龙嫩漫步时那种放空大脑一个人立于天地间的平静,不过后面突然狂风暴雨又是另外一回事了[裂开]

6月7号 弦圈APP于高考首日的更新日志😀

这段时间虽然因为很多突发事情导致耽搁了APP的上架,但是我还是给弦圈APP进行了大量的修改和优化。新版的APP还是叫做V1.0版吧,新版APP主要变动如下:添加微信分享、QQ分享功能,方便用户分享弦圈内容。接上,添加圈子分享、文章分享、帖子分享、图片分享功能。其中圈子、文章、帖子分享包括微信好友分享、朋友圈分享、QQ好友分享、QQ空间分享。添加忘记密码功能。该功能原本只有Web端有,现在手机APP端补上。添加扫码登录功能。在弦圈Web端,用户可以通过APP扫码的方式进行登录。圈子中添加查看标签功能,相当于圈子内容的二次分类。该功能原本只有Web端有,现在手机APP端补上。写文章和提问题功能中的“添加词条”,原本只能选择原有词条,不能创建新词条。现在在这个地方允许用户快速新建词条。优化页面样式,修复部分机型导航栏遮盖问题(见 应用详情-注意事项)。值得一提的是该问题微信、QQ等APP都有😀。修复圈子中样式不改变以及样式错乱bug。修复APP端帖子与Web端帖子不兼容问题。修改APP开屏启动图案样式,之前的启动图案太小了😅,看得不舒服。目前只记得改过那么多东西了,就这10点改变,每一点都要 ...