今天学到了JS的关于深拷贝和浅拷贝的例子,有些体会。
在JavaScript中,变量的拷贝分为两种,一种是值拷贝,一种是内存地址拷贝,意思是当赋值给变量的只是一个简单的基本数值时,变量与变量之间的储存空间是相互独立,两个变量之间的改变不会相互影响,而当赋值给变量的是一个对象或数组的时候,变量与变量之间的存储空间将会指向同一个内存空间,当某一个变量改变时,内存空间的值也会改变。
//值拷贝
var i = 4;
var j = i;
//内存地址拷贝
var m = {name:'xxx'};
var n = m;
浅拷贝,只是简单的变量赋值,如果赋值的变量是引用类型的对象,变量之间会共享一个内存空间,每个变量的修改都会影响内存空间里的值;深拷贝,也就是实现将引用类型的数据值拷贝到另一个新创建的储存空间里。
//浅拷贝
var obj1 = {name = 'xxx'};
var obj2 = obj1;//指向同一个内存地址
//深拷贝
var obj1 = {name = 'xxx'};
var obj2 = {};//创建一个新空间
obj2.name = obj1.name;//存放name的数值
这是一个比较简单的对象的拷贝,再来看一个比较复杂的:
var people = {
name:'xxx', //基本数值
friends:['people1','people2','peopple3'], //数组
info:{ //对象
phone:'133xxxxxxxx',
age:'18',
sex:'man'
}
}
如果这种复杂的对象只是简单的赋值给另一个变量的,那就是浅拷贝,这样我们会遇到一些问题:
var man1 = people;
var man2 = people;
man1.name = '李四'; //man2的名字也变成李四
man1.friends[0] = '张三';//man2的第一个朋友也变成了'张三'
man1.info.age = '20';//man2的年龄也变成了20
所以我们需要将每个数组和变量都进行复制。我们可以封装一个函数,用来深拷贝:
function(obj,copy){
for(var i in obj){
copy[i] = obj[i];//复制obj中的每一个项
}
return copy;
}
这样写还是有问题就是当obj中的某个属性任然是引用类型的变量时,依然会指向同一个内存空间。所以我们就可以用递归的方法,让是对象的属性再通过遍历来赋值。
function deepCopy(obj,copy){
for(var i in obj){
if(typeOf obj[i] == 'object'){ //判断是否为对象
deepCopy(obj[i],copy[i]);//回调深拷贝函数
}
else{
copy[i] = obj[i]; //不是对象直接复制
}
}
return copy;
}