浅拷贝:复制一层对象的属性,并不包括对象里面的为引用类型的数据,当改变拷贝的对象里面的引用类型时,源对象也会改变。·
深拷贝:重新开辟一个内存空间,需要递归拷贝对象里的引用,直到子属性都为基本类型。两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。
javaScript的变量类型:
1)基本类型:
5种基本数据类型Undefined、Null、Boolean、Number 和 String,变量是直接按值存放的,存放在栈内存中的简单数据段,可以直接访问。
(2)引用类型:
存放在堆内存中的对象,变量保存的是一个指针,这个指针指向另一个位置。当需要访问引用类型(如对象,数组等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。
JavaScript存储对象都是存地址的,所以浅拷贝会导致 obj1 和obj2 指向同一块内存地址。改变了其中一方的内容,都是在原来的内存上做修改会导致拷贝对象和源对象都发生改变,而深拷贝是开辟一块新的内存地址,将原对象的各个属性逐个复制进去。对拷贝对象和源对象各自的操作互不影响。
对浅拷贝的实现方式:
var person={
name:"cj",
age:22,
address:{
home:"home address",
office:"office address",
}}
var programer={
language:"javascript"
}function extend(p,c){
var c=c ||{}
for(var prop in p){
c[prop]=p[prop]
}
}
对浅拷贝的测试
extend(person,programer)
undefined
programer.name
"cj"
programer.age
22
programer.address
{home: "home address", office: "office address"}
programer.language
"javascript"
programer.name="abc"
"abc"
person.name
"cj"
programer.address.home="adwa"
"adwa"
person.address.home
"adwa"
当address 是一个对象,当浅拷贝时复制的是address的地址,当新对象的home发生改变时,源对象的home也会发生改变
深拷贝 :
深拷贝实现方式:
var person={
name:"cj",
age:22,
address:{
home:"home address",
office:"office address",
},schools:["xiaoxue","daxue"]
}
var programer={
language:"javascript"
}function extendDeeply(p,c){
var c=c||{};
for (prop in p){
if(typeof p[prop]==="object"){
c[prop]=(p[prop].constructor===Array)?[]:{};
extendDeeply(p[prop],c[prop]);
}else{
c[prop]=p[prop];
}
}
}
经过深拷贝之后 就不会改变原对象
extendDeeply(person,programer)
undefined
programer.schools[0]
"xiaoxue"
programer.schools[0]="adasdasd"
"adasdasd"
person.schools[0]
"xiaoxue"