javascript深浅拷贝

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

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

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

 

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

基础类型存在于栈中

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

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

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

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

 

posted @ 2020-01-23 16:17  gsq1998  阅读(218)  评论(0编辑  收藏  举报