理解js浅拷贝和深拷贝
理解深拷贝和浅拷贝之前先了解下js中的基本类型和引用类型
1、基本类型:
在js中,数据的基本类型undefined,null,string,number,boolean,在变量中赋的实际值,基本类型就是简单的数据段。
基本类型的值是不可以改变的
var a = 1;
var b = a;
a++;
console.log(a); //2
console.log(b); //1
这里a和b是独立的,当改变a或b,其另外一个值不会随之改变
2、引用类型:
在js中,数据的引用类型object,Array,RegExp,date,function,在变量中赋的实际值
引用类型的值是可以改变的
var arr = [1,2,3,4,5];
var arr2 = arr;
arr[0] = 2;
console.log(arr); //[2、2、3、4、5]
console.log(arr2);//[2、2、3、4、5]
这里在改变arr[0]中的值后,arr2数据也跟着改变,引用类型在赋值的时候(arr2=arr),其实在栈内存中添加了arr2,但是堆内存中还是[1,2,3,4,5],通俗点讲就是引用类型赋值并非真正意义上的数据赋值,而是在栈内存中添加一个指针,还是指向堆内存中的[1,2,3,4,5],只添加栈内存的指针
好,到这里我们在讨论深拷贝和浅拷贝,深拷贝顾名思义是在数据是相互独立的,改数据而另一个不受影响,浅拷贝则是数据会随之改变而改变。
这么一看,基本类型不正好是嘛,数据都是相互独立的,乍看好像还真是的。
但是,但是,我们所说的深拷贝必须要在复杂的object类型下,基本类型里没有object,那么只能是引用类型。
再来看个例子:
var arr3 = [[1,2],3,4,5];
var arr4 = arr3;
arr3[0][1] = 3;
console.log(arr3); //[[1,3],3,4,5]
console.log(arr4); //[[1,3],3,4,5]
明明改了arr3,为何arr4也改了,这不是我想要的,那如何独立呢,你会发现使用什么for循环,slice,concat是根本不管用的,网上有其他的坑,在此我就不多说了,直接说解决办法
方法1、JSON
利用JSON.stringify和JSON.parse
var arr3 = [[1,2],3,4,5];
var arr4 = JSON.parse(JSON.stringify(arr3));
arr3[0][1] = 3;
console.log(arr3); //[[1,3],3,4,5]
console.log(arr4); //[[1,2],3,4,5]
但是这种方法有个小弊端,就是值不能为undefined或null,最好对数据提前判断
方法2、jq $.extend
$.extend([deep],target,object1[,objextN]); //deep 值为true或false,true为深拷贝,false为浅拷贝。target 目标对象,其他对象的成员属性将被附加到该对象上 object1/objextN 是需要被操作的对象,可以是多个,这里是例子中的arr3
var arr3 = [[1,2],3,4,5];
var arr4 = $.extend(true,[],arr3);
arr3[0][1] = 3;
console.log(arr3); //[[1,3],3,4,5]
console.log(arr4); //[[1,2],3,4,5]
以上就是介绍的两种方法