1、拷贝,先区分数据
基本数据类型:number,string,null,undefined,布尔,sybomt
基本数据类型,存储直接存储在栈内(没有深浅拷贝的概念,只有赋值概念)
引用数据类型:array,object,function(除基本数据类型,都是引用数据类型,也都属于顶层object)
引用数据类型,值存堆内存,栈存的是值的引用地址 (通过引用地址找到堆里面的值)
堆 先进先出 栈 先进后出 堆容量比栈大 栈比堆的运算速度快
实例说明
基础数据类型直接赋值 会在栈内存中新开辟一个空间储存赋值的值*
let s1 = 1;
let s2 = s1;
s1 = 2
console.log('s1原值:>> ', s1);
打印结果:2
console.log('s2基础数据类型赋值 :>> ', s2);
打印结果:1
双方并无影响
引用数据类型直接赋值 直接赋值后,obj2得到的只是obj1值的引用地址,此时obj1和obj2引用地址一样,指向堆内存的值也是同一个
let obj1 = {
name:'zx',
age:18,
mother:{
name:'zz'
}
};
let obj2 = obj1;
obj1.name = 'gaiz'
console.log('obj1原值 :>> ', obj1);
console.log('obj2引用数据类型赋值 :>> ', obj2);
值跟着变化了
1、拷贝
1、 浅拷贝只能拷贝一层的基本数据类型,它只会复制其基本值的引用
重点:最外层的引用地址变了,但是内层的引用对象的引用地址没变
2、 浅拷贝:A拷贝B, (A的最外层引用地址是新的)B值改变, A引用地址和B不同, 所以A值不受B改变。但因为只能拷贝一层 所以 如果数据中是包含了'子'对象则数据一同变化
3、 深拷贝:A拷贝B,(A的引用地址和堆里面存的值,都是新的),A,B值互不影响,引用地址也不同
浅拷贝
最外层拷贝,最内层引用地址没变,指向的堆也是一样的
1、 Object.assign({},源对象)
方法的第一个参数是目标对象,后面的参数都是源对象
let obj1 = {
name:'zx',
age:18,
mother:{
name:'zz'
}
};
let obj3 = Object.assign({},obj1);
obj1.name = '浅浅的变化';
console.log('obj1主动改变name值 :>> ', obj1);
console.log('obj1改变obj3未变化 :>> ', obj3);
浅拷贝第一层,值没跟着变化
obj1.mother.name = '多一层则不行了';
console.log('obj1主动改变name值 :>> ', obj1);
console.log('多一层obj1改变obj3被影响 :>> ', obj3);
下图查看,嵌套深一层,拷贝失效。
2、展开运算符 【...】 {...}
可以明显看到第一层的obj.name互不影响,深一层的.mother同时变化了
还有一些浅拷贝不赘述,理念概念就好。
深拷贝
完全开辟一个新的栈,两个不同的地址。