js中数据类型分为:
基本数据类型:Number,String,Boolean,Null,Undefined,Symbol
对象数据类型(引用数据类型):Object
引用数据类型的值是保存在栈内存和堆内存中的对象.栈区内存内存保存变量标识符和指向堆内存中该对象的指针.当寻找引用值时,解释器会先寻找栈中的地址.然后根据地址找到堆内存的实体.
浅拷贝
浅拷贝会将对象的每个属性进行依次复制,但是当对象的属性值是引用类型时,实质复制的是其引用,当引用指向的值改变时也会跟着变化.
深拷贝
深拷贝和浅拷贝是针对复杂数据类型来说的,浅拷贝只拷贝一层,而深拷贝是层层拷贝.
深拷贝复制变量值,对于非基本类型的变量,则递归至基本类型变量后,再复制.深拷贝后的对象与原来的对象是完全隔离的,互补影响,对一个对象的修改并不会影响另一个对象.
数组(注意:该数组只是单纯的数组,如果数组里面嵌套对象,则下面的几种方法都不是深拷贝)实现深拷贝的几种方法:
1.使用递归的方法.for循环
let arr1 = [1,2,3];
let arr2 = copyArr(arr1);
function copyArr(arr){
let res=[];
for(let i=0,length=arr.length;i<length;i++){
res.push(arr[i]);
}
return res;
}
2.数组的slice方法或者concat方法
let arr1 = [1,2,3];
let arr2 = arr1.slice(0);
let arr1 = [1,2,3];
let arr2 = arr1.concat();
3.拓展运算符
let arr1 = [1,2,3];
let [...arr2] = arr1;
4.Array.from
Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组,也是ES6的新增方法。
let arr1 = [1,2,3];
let arr2 = Array.from(arr1);
对象实现深拷贝的几种方法:
1.for循环
let obj1={count:1,name:'grace',age:1};
let obj2 = copyObj(obj){
let res = {};
for(let key in obj){
res[key]=obj[key];
}
return res;
}
2.使用JSON转换
let obj1={count:1,name:'grace',age:1};
let obj2 = JSON.parse(JSON.stringify(obj1));
3.使用拓展运算符
let obj1={count:1,name:'grace',age:1};
let {...obj2} = obj1;
总结:
浅拷贝针对的是基本数据类型,只改变栈内存.深拷贝针对的是引用数据类型,针对的是堆内存,引用数据类型的栈内存存放的是堆内存的地址.