javascript深浅拷贝

摘要:
1: 首先,让我们看一下js的基本数据类型:undefined、null、number、string、boolean、Symbol引用类型:对象对象类型2:关于这两种类型,有几个关键知识点。堆栈中存在基本类型。引用类型的值是存储在堆栈内存和堆内存中的对象javascript变量的存储方法。堆栈和堆有几个关于堆栈和堆的关键点。1.堆栈是后进先出,堆是先进先出。2.堆栈内存是手动分配的,而堆内存是自动分配的。

一:首先我们先来看一下js有哪些基础数据类型

基础类型:undefined,unll,number,string,boolean,symbol

引用类型:object对象类型(object,array,function,data)

二:对于这两种类型有几个关键知识点

基础类型存在于栈中

javascript深浅拷贝第1张

引用类型的值是同时保存在栈内存和堆内存中的对象

javascript深浅拷贝第2张

javascript的变量的存储方式 栈(stack) 和堆(heap)

javascript深浅拷贝第3张

关于栈和堆有几个关键点需要了解

1 栈(stack)是后进先出,堆(heap)是先进先出。

2 栈(stack)内存是我们手动分配, 堆(heap)内存是自动分配。

1 对象和数组的赋值操作

对象:

1         let obj1 = {name:'gsq',age:18}
2         let obj2 = obj1
3         console.log(obj1.age === obj2.age); //true
4         obj2.age = 90
5         console.log(obj1.age === obj2.age); //true 

我们发现当修改了obj2的age的时候obj1也跟着改变

对于这种对象赋值,两个对象指向的事同一块内存地址,当对象获取key值然后重新赋值,是可以改变值的,这样可以寻找到对象的指针。如果直接改变值,这样是不可以改变的。因为寻不到地址。

数组:

1         let arr1 = [1,2,3,4,5]
2         let arr2 = arr1
3         console.log(arr1[0] === arr2[0]) //true
4         arr2[0] = 1000
5         console.log(arr1[0] === arr2[0])  //true

发现也是和对象是一样的,arr1和arr2是这个数组对象的一个堆引用地址,指向的是同一个对象

好了,以上就是对数据类型基本的认识

浅拷贝

        修改新变量的值会影响原有的变量的值
        默认情况下引用类型都是浅拷贝
 1         let a = {
 2             "fdf":12,
 3             "fdttf":[1,2,3,45,6],
 4             "fdfdfd":{
 5                 "rere":"rerer",
 6                 "erer":{
 7                     "fdfdffd":122323
 8                 }
 9             }
10         }
11         let b = {
12 
13         }
14         //1:使用方法的形式  只能拷贝第一层
15         // assign方法是将a的所有的值赋值到b中
16         // Object.assign(b,a)
17         // console.log(b); //跟a一模一样
18         // b.fdf = "434545" //修改b的fdf键的值
19         // console.log(a.fdf) //输出12  ,发现这个2个对象是都有一个独立的内存空间了
20 
21         //2:自己实现 只复制一层的浅拷贝
22         // for(let key in a){
23         //     b[key] = a[key]
24         // }
25         console.log(b);
26         b.fdf = "fdfdfdfdfdfdfdf"; //修改第一层的基本类型数据
27         console.log(a.fdf);  //发现,修改后与b无瓜
28         b.fdttf = "dfsfdsfsdf"  //修改第一层的基本类型数据
29         console.log(a.fdttf); //发现,修改后与b无瓜
30         b.fdfdfd.rere = "fdfdfdfdfdfdfdf"; //修改第二层的基本类型数据
31         console.log(a.fdfdfd.rere)  //发现,修改后与b有瓜
深拷贝
        修改新变量的值不会影响原有变量的值
        默认情况下基本数据类型都是深拷贝
  
自己实现的方法
 1         let a = {
 2             "fdf":12,
 3             "fdttf":[1,2,3,45,6],
 4             "fdfdfd":{
 5                 "rere":"rerer",
 6                 "erer":{
 7                     "fdfdffd":122323
 8                 }
 9             }
10         }
11         let b = {
12 
13         }     
14         // 封装一个深拷贝的函数
15         function depCopy(target, source) {
16             // 1.通过遍历拿到source中所有的属性
17             for(let key in source){
18                 // console.log(key);
19                 // 2.取出当前遍历到的属性对应的取值
20                 let sourceValue = source[key];
21                 // console.log(sourceValue);
22                 // 3.判断当前的取值是否是引用数据类型
23                 if(sourceValue instanceof Object){
24                     // console.log(sourceValue.constructor);
25                     // console.log(new sourceValue.constructor);
26                     let subTarget = new sourceValue.constructor;
27                     target[key] = subTarget;
28                     depCopy(subTarget, sourceValue);
29                 }else{
30                     target[key] = sourceValue;
31                 }
32             }
33         }
34 
35         depCopy(b,a);
36         b.fdfdfd.rere = "fdfdfdfdfdfdfdf1323"
37         console.log(a.fdfdfd.rere === b.fdfdfd.rere); //false

免责声明:文章转载自《javascript深浅拷贝》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【讲座】朱正江——基于LC-MS的非靶向代谢组学java基础知识回顾之javaIO类--内存操作流ByteArrayInputStream和ByteArrayOutputSteam(操作字节数组)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Linux下使用VSCode开发OpenCV程序

在Linux下使用VSCode开发OpenCV程序,并使用cmake编译 创建项目 打开vscode,选择File->Open Folder VSCode配置 这里需要配置launch.json, tasks.json, c_cpp_properties.json三个文件; launch.json配置 点击左侧Debug, 选择Add Configu...

通过Bochs分析Lilo启动Linux内核的过程

1. Bochs调试 参考:http://www.cnblogs.com/long123king/p/3414884.html http://bochs.sourceforge.net/cgi-bin/topper.pl?name=New+Bochs+Documentation&url=http://bochs.sourceforge.net/do...

Qt for Android 部署流程分析

原地址:http://blog.csdn.net/foruok/article/details/17796017 今天为了测试使用 Qt Creator 3.0.0 开发的纯 C 工程,利用了Windows 下 Qt 5.2 for Android 开发入门里创建的 HelloAndroid 工程,想把纯 C 工程生成的 so 库加到 HelloAndro...

MappedByteBuffer

计算机内存管理 原文链接https://www.cnblogs.com/guozp/p/10470431.html MMC:CPU的内存管理单元。 物理内存:即内存条的内存空间。 虚拟内存:计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘...

python基础知识5——赋值与深浅拷贝——整数和字符串,列表元组字典

深浅copy      和很多语言一样,Python中也分为简单赋值、浅拷贝、深拷贝这几种“拷贝”方式。 在学习过程中,一开始对浅拷贝理解很模糊。不过经过一系列的实验后,我发现对这三者的概念有了进一步的了解。 一、赋值 赋值算是这三种操作中最常见的了,我们通过一些例子来分析下赋值操作: str例 1 >>> a = 'hello' 2 &...

为什么完整备份不能截断事务日志

导言 完整备份不能截断事务日志,这是所有SQL Server DBA的一个常识, 为此,当数据库处于完整恢复模式时(非特别说明,下文所提到都是完整恢复模式下的数据库),DBA们必须频繁地使用事务日志备份的方式来防止日志文件变得过大。 这几乎成为了DBA们的一个定理,但,作为一个DBA,你证明过这个定理吗?你知道为什么完整备份不能截断事务日志吗? 一个错误的...