一 . 概念
浅拷贝 -- 创建一个新对象,让这个新对象对原始对象的值做一份精确拷贝,如果原始对象的属性值是基本数据类型,拷贝的就是值,如果原始对象的属性值是一个引用数据类型,拷贝的就是内存地址,所以如果在新对象中修改这个属性值,那么对应的院士对象中的引用类型值也会发生变化,类似于你和自己的影子一样。
深拷贝 -- 创建一个新对象,将原对象从内存中完全拷贝一份出来,新对象会在内存中开辟一块新内存地址用来存放拷贝过来的源对象的属性,冰球修改新对象不会影响原始对象。比如两个双胞胎。
二 . 浅拷贝实现
使用 for 循环
function clone(originObj) { let newObj = Array.isArray(originObj)? [] : {}; for (const key in target) { newObj[key] = originObj[key]; } return newObj; };
三 . 深拷贝实现
数组深拷贝
var arr1 = ['java','python','ruby','c#','php'] var arr2 = JSON.parse(JSON.stringify(arr1)) console.log(arr2) // ["java", "python", "ruby", "c#", "php"] // 修改 arr2 第一个元素 arr2[0]="javascript" console.log(arr2) // ["javascript", "python", "ruby", "c#", "php"] console.log(arr1) // ["java", "python", "ruby", "c#", "php"] // arr2 的修改并没有影响到 arr1 的元素变化
对象深拷贝
var objA = { name:"LILI", age:12, hobby:["吃饭","睡觉","打豆豆"], say:function(){ return "I'm " + this.name + ", and my years old " + this.age } }; var objB = JSON.parse(JSON.stringify(objA)); // 分别输出 objA 和 objB 发现objB确实拷贝了objA的属性,但是方法无法(函数)实现拷贝
总结:使用 JSON 对象方法写法比较简单,可以适用于大部分应用场景,但是拷贝其他引用类型,比如函数,循环引用等都无法实现。
手动封装实现深拷贝
for 循环配合递归实现一个基础的深拷贝
function deepClone(originObj){
if(typeof originObj === 'object' ){
// 根据原对象是一个数组引用类型还是一个对象,来确定新对象初始值是一个数组还是一个对象
let newObj = Array.isArray(originObj) ? [] : {}
for(let key in originObj){
newObj[key] = deepClone(originObj[key]) // 递归
}
return newObj
}else{
return originObj
}
}