浅拷贝只是拷贝一层(基础数据类型),更深层次对象级别的拷贝引用(复合数据类型) 第一种: 浅拷贝
需求:把 obj拷贝给 o
let obj ={id:1, name:"and" , msg{ age: 18} };
let o ={};
方法一:
利用遍历实现浅拷贝
for(let k in obj) {
注: k代表属性名 obj[k]代表属性值
o[k] = obj[k];
}
o.msg.age = 20 ; //修改其中一个
打印 obj.msg.age 和 o.msg.age ?
结果都是20说明:(复合数据类型)只是拷贝(地址存在栈里)给新对象 o ,指向同一个堆数据,彼此修改有影响。
方法二:推荐使用 ES6新增方法可以浅拷贝
语法:Object.assign(给谁浅拷贝,被拷贝的)
Object.assign(o,obj)
打印 obj.msg.age 和 o.msg.age ?
结果同上一致
浅拷贝(复合数据类型)如图:
深拷贝拷贝多层,每一级别的数据都会拷贝
通俗:深拷贝(复合数据类型),在堆开辟自己内存空间复制(复合数据类型),彼此修改不影响彼此
需求:把 obj拷贝给 o
let obj ={id:1, name:"and" , msg{ age: 18} ,arr : ['red','pink']};
let o ={}
方法一:利用递归函数,拷贝多层(复合类型数据)
funtion deepCopy (new , old){
for(let k in old ) {
k代表属性名 old[k]代表属性值
let item =old[k]; 注:存储属性值用于判断类型
1.判断数据属于那种类型
if(item instanceof Array){
2. 判断这个值是否是数组(复合数据类型)
new[k] = [] ; 注:是数组类型,值先定义空数组,方便数据
deepCopy ( new[k] , item) 注:把旧值(这里代表obj)深拷贝给新值(这里代表o)
}else if( item instanceof Object ){
3. 判断这个值是否是对象(复合数据类型)
new[k] = {} ;
deepCopy ( new[k] , item)
}else{
4. 属于(基础数据类型)
new[k] = item;
}
}
}
deepCopy (o , obj)
5.修改新对象中的 o.msg.age=20
打印 obj.msg.age 和 o.msg.age
结果20,18
说明:深拷贝(复合数据类型),新对象(o)在堆内存开辟自己空间存储复制的数据,彼此修改不影响彼此。
浅拷贝多层(复合数据类型)如图:
总结:
-
浅拷贝: 拷贝(复合数据类型)的地址(注:这个地址存在栈里)指向同一个堆数据,彼此修改影响彼此。
-
深拷贝 拷贝(复合数据类型),在堆开辟自己内存空间,存储复制好的"复合数据类型",彼此修改不影响彼此。
-
js中变量传值两种形式: (1)值传递:彼此修改没有影响(基础数据类型)
(2)引用传值:彼此的修改有影响(复合数据类型),也叫共享引用
注:所有的变量名都是栈