Bootstrap

深拷贝和浅拷贝

浅拷贝

所谓的浅拷贝就是拷贝指向对象的指针,意思就是说:拷贝出来的目标对象的指针和源对象的指针指向的内存空间是同一块空间.浅拷贝只是一种简单的拷贝,让几个对象公用一个内存,然而当内存销毁的时候,指向这个内存空间的所有指针需要重新定义,不然会造成指针错误

深拷贝

所谓的深拷贝指拷贝对象的具体内容,其内容地址是自助分配的,拷贝结束之后,内存中的值是完全相同的,但是内存地址是不一样的,两个对象之间相互不影响,也互不干涉.

 

在使用JavaScript对数组进行操作的时候,如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致了问题的发生。

var arr = ['aa','bb','cc'];

var arr2 = arr;

arr2[0] = '新来的';

console.log(arr);//输出  '新来的','bb','cc'

由此可见对数组arr2进行修改时,而arr内数据也会随之改变。这种直接赋值的方式就是浅拷贝现象。 一般都是开辟一块新的内存地址,将原对象的各个属性逐个复制出去。

一、数组深拷贝

1、遍历

var a = [1,2,3];

var deepArry = [];

function deepCopy(arry1, arry2){

    for(var i = 0,l= arry1.length;i<l;i++){

        arry2[i] = arry1[i];

    }

}

deepCopy(a,deepArry);

console.log(a);

console.log(deepArry);

 

2、slice方法

var arr = ["One","Two","Three"];

var arr_2= arr.slice(0);

console.log(arr_2 )

 

3、concat方法

var arr = ["One","Two","Three"];

var arr_2= arr.concat();

console.log(arr_2);

 

注:Array的slice和concat方法

 

Array的slice和concat方法不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。之所以把它放在深拷贝里,是因为它看起来像是深拷贝。而实际上它是浅拷贝。原数组的元素会按照下述规则拷贝:

 

如果该元素是个对象引用 (不是实际的对象),slice 会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。

对于字符串、数字及布尔值来说(不是 String、Number 或者 Boolean 对象),slice 会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。

如果向两个数组任一中添加了新元素,则另一个不会受到影响。例子如下:

 

var array = [1,2,3]; 
var array_shallow = array; 
var array_concat = array.concat(); 
var array_slice = array.slice(0); 
console.log(array === array_shallow); //true 
console.log(array === array_slice); //false,“看起来”像深拷贝
console.log(array === array_concat); //false,“看起来”像深拷贝

 

可以看出,concat和slice返回的不同的数组实例,这与直接的引用复制是不同的。而从另一个例子可以看出Array的concat和slice并不是真正的深复制,数组中的对象元素(Object,Array等)只是复制了引用。如下:

 

var array = [1, [1,2,3], {name:"array"}]; 
var array_concat = array.concat();
var array_slice = array.slice(0);
array_concat[1][0] = 5;  //改变array_concat中数组元素的值 
console.log(array[1]); //[5,2,3] 
console.log(array_slice[1]); //[5,2,3] 
array_slice[2].name = "array_slice"; //改变array_slice中对象元素的值 
console.log(array[2].name); //array_slice
console.log(array_concat[2].name); //array_slice

二、对象深拷贝

var a={name:'yy',age:26};

var b=new Object();

b.name=a.name;

b.age=a.age;

a.name='xx';

console.log(b);//Object { name="yy", age=26}

console.log(a);//Object { name="xx", age=26}

 

1、json方法

var obj= {a:1,b:2};

var str = JSON.stringify(obj);//这里将json内的数据转换成一个字符串存起来

var obj_2= JSON.parse(str);//这里将字符串的内容"还原"成原来的"面目"

console.log(obj_2);//输出 {a:1,b:2}

 

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;