数据深拷贝和浅拷贝
1.首先要理解什么是js数据存储方法
JS的数据类型分成两种:基本数据类型和复杂数据类型
JS数据基本类型定义一般有5种:number(数字)、string(字符串)、boolean(布尔类型)、null(null类型)、undefined(underfind类型)。
复杂数据类型一般是指引用类型,就是Object。其中包含了(array,Object,function)等等
基本数据类型主要存储在栈里面,取用赋值的时候是值传递
复杂数据类型也就是引用类型,他的指针(也就是引用)一般存在栈中,值存在堆中,那什么是指针,其实指针就像开车时遇到的路牌,值就像是目的地,我们通过路牌找到目的地,这里则是通过指针找到我们所需要的值。
2.什么是深拷贝和浅拷贝呢?
其实对于基本数据类型,没有深浅拷贝的说法,因为一般赋值后把值传递给了新的变量,两者就没有关系了。
var a = 133;
var b = a;
b++;
console.log(a)//133
console.log(b)//134
由上面的例子可以看到a,b两者赋值后就没有关系了。
而对于复杂数据类型则有所不同
浅拷贝
对于复杂数据类型,直接赋值
var a = {obj:1}
var b = a;
b.obj=2;
console.log(a)//{obj: 2}
console.log(b)//{obj: 2}
我们改变了b对象的属性,发现a对象的属性也发生改变了
原因在于我们b=a时,是把a的引用赋值给b,而不是创建新的空间将其复制下来,所以a,b都是指向原来堆中的{obj:1},所以b改变值时,改变的是{obj:1}的值,所以a的属性也发生了变化
这就是我们的浅拷贝
深拷贝
一般来说我们处理赋值一般是想把他们初始化,并且后续操作两者不会相互影响;
这个时候需要深拷贝了
深拷贝的意思是指在拷贝a的过程中,创建新的对象以及新的堆空间的值,使a的值等于b的值,a,b后续操作没有影响。
对于数组
1.用返回一个新的数组的方法做拷贝
var a = [1,2,3,4];
//方法一 slice
var b = a.slice(0)
console.log(b)
//方法二 concat
var c = a.concat()
//...还有很多很多操作数组返回新的数组就不一一列举了
对于对象
let obj1 = {name:obj1}
//方法一扩展运算符,数组也行
let {...obj} = obj1;
//方法二 利用json转换
let obj2 = JSON.parse(JSON.stringify(obj1));
//方法三 用for循环
function copy(obj){
let res = {};
for(let key in obj){
res[key] = obj[key]}
return res;}
let obj3 = copy(obj1)
在网上找到一个综合数组和对象的方法
function deepCopy(obj){
let result = Array.isArray(obj)?[]:{};
if(obj && typeof obj === 'object'){
for(let key in obj){
if(obj.hasOwnProperty(key)){
if(obj[key]&&typeof obj[key]==='object'){
result[key]=deepCopy(obj[key]);
}else{
result[key]=obj[key];
}
}
}
}
return result;
}