js深浅复制

275 阅读1分钟

1、数据类型

值类型(基本类型):String、Number、Boolean、Null、Undefined、Symbol(ES6)

引用类型:Object、Array、Function

2、浅拷贝

浅拷贝只是拷贝基本类型的数据,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,因此存在父对象被篡改的可能,浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存

浅拷贝方法及其缺点

3、深拷贝

深拷贝就是能够实现真正意义上的数组和对象的拷贝。递归调用"浅拷贝"。(深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象)

深拷贝方式及其缺点

// 迭代递归法:深拷贝对象与数组--for in
function deepClone(obj) {
if (!isObject(obj)) {
throw new Error('obj 不是一个对象!')
}
let isArray = Array.isArray(obj)
let cloneObj = isArray ? [] : {}
for (let key in obj) {
cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
}
return cloneObj
}




// 代理法-Reflect
function deepClone(obj) {
if (!isObject(obj)) {
throw new Error('obj 不是一个对象!')
}
let isArray = Array.isArray(obj)
let cloneObj = isArray ? [...obj] : { ...obj }
Reflect.ownKeys(cloneObj).forEach(key => {
cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
})
return cloneObj
}


//自定义深复制 
function objectClone(targetObj,sourceObj){ 

   var names = Object.getOwnPropertyNames(sourceObj);    for(var i=0;i<names.length;i++){ 

     var desc = Object.getOwnPropertyDescriptor(sourceObj,names[i]); 
     if(typeof(desc.value)==='object'&&desc.value!==null){ 
        var obj={ }; 
        Object.defineProperty(targetObj,names[i],{ 
         configurable:desc.configurable, 
         enumerable:desc.enumerable, 
         writable:desc.writable, 
         value:obj 
        }); 
        objectClone(obj,desc.value); 
     }else{ 
        Object.defineProperty(targetObj,names[i],desc); 
     } 
     } 
      return targetObj; 
 }