拷贝分为深拷贝与浅拷贝
浅拷贝:只能复制基本类型的值,不能复制引用类型的值;
浅拷贝的基本类型的值是各自独立的,而引用类型的值还是和之前的对象一样是公用的
深拷贝:即创建了一个新的对象;
这个对象中基本类型值是独立的,引用类型值也是独立的,修改这个对象的引用类型的值不会影响原对象的值。
如何实现浅拷贝?
①es6新增的Object.assign方法,可接受多个参数,第一个对象为目标对象,后面的为源对象
var target = {}; // 目标对象
var source = {a : 1}; // 源对象
Object.assign(target,source);
// target = {a : 1};
②自己创建函数
function shallowCopy(objNew,obj){ // 目标对象和原对象
var objNew = objNew||{};
for(let i in obj){
objNew[i] = obj[i];
}
return objNew;
}
如何实现深拷贝
实现深拷贝的主要思想就是当属性是对象或者数组的时候,就创建新的对象或者数组,递归,直到出现基本值,将基本值复制到对象或者数组当中,最后返回创建的这个新的对象或者数组。
①转成json再转回来
var obj = {
num:1,
array:[1,2,3]
}
var str = JSON.stringify(obj);
console.log(str); // "{"num":1,"array":[1,2,3]}"
var objNew = JSON.parse(str);
console.log(objNew); // {num: 1, array: Array(3)}
②自定义函数
function deepCopy(opt,obj){ // 参数分别为目标对象和原对象
var objNew = opt||{};
for(let i in obj){
// 如果当前属性是对象
if(typeof i === 'Object'){
if(obj[i].constructor === Array){
objNew[i] = [];
}else if(obj[i].constructor === Object){
objNew[i] = {};
}
deepCopy(objNew[i],obj[i]);
}else{ // 否则直接相等
objNew[i] = obj[i];
}
}
return objNew;
}
总结
深拷贝主要用在一些不希望改变原对象的情况下复用对象,比如后台传过来一个 json 对象,自己测试的时候不希望改变这个对象,可以拷贝一个,对拷贝的对象进行操作。
浅拷贝主要复制的是对象的基本类型的值,而引用类型值和原对象还是共用一个,所以修改新对象的引用类型值会影响原对象,这往往是我们不想要的,所以需要注意。