JS深拷贝与浅拷贝及深拷贝的三种实现方法
前置知识
基本类型: number string boolean undefined null
引用类型: Array Function Object
-
基本数据类型直接存储在栈中
var a=1
-
基本类型直接的复制 是直接复制一份数据放到栈空间
var b=a
-
引用数据类型在栈中存储一个指向堆的指针
var a = new Object()
3. 这个指针指向的位置存储着对象的值
a.name="myName"
首先我们需要知道深拷贝主要是对于嵌套对象和数组来说的
浅拷贝(copy):是对于一个对象的顶层拷贝,拷贝父对象,不会拷贝对象的内部的子对象。
深拷贝(deepcopy): 是对于一个对象所有层次的拷贝(递归),完全拷贝了父对象及其子对象。
测试代码
const obj1 = {
age: 20,
address: {
city: 'beijing'
},
arr: ['a', 'b', 'c']
}
//方法一
const obj2 = deepCopy1(obj1)
//方法二
//const obj2 = deepCopy2(obj1)
//方法三
//const obj2=$.extend(true,[],obj1);
// 下面三行测试 对象是否是深copy
obj2.address.city = 'shanghai'
console.log("obj1.address.city", obj1.address.city); //obj1.address.city beijing
console.log("obj2.address.city", obj2.address.city);//obj2.address.city shanghai
// 下面三行测试 数组是否是深copy
obj2.arr[0] = 'a2'
console.log("obj1.arr[0]", obj1.arr[0]);//a
console.log("obj2.arr[0]", obj2.arr[0]);//a2
方法一 :递归复制所有层级属性。
function deepCopy(obj = {}) {
if (typeof obj !== 'object' || obj == null) {
// obj 是nul 或者不是对象和数组,直接返回
return obj
}
// 初始化返回结果
let result
if (obj instanceof Array) {
result = []
} else {
result = {}
}
for (let key in obj) {
// 保证key不是原形的属性
if (obj.hasOwnProperty(key)) {
// 递归调用
result[key] = deepCopy(obj[key])
}
}
// 返回结果
return result
}
方法二:借用JSON对象的parse和stringify方法实现深拷贝
function deepCopy2(obj = {}){
let _obj = JSON.stringify(obj),
objClone = JSON.parse(_obj);
return objClone
}
方法三 : 使用jQuery的extend方法
$.extend( [deep ], target, object1 [, objectN ] )
其中deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
target: 目标对象,其他对象的成员属性将被附加到该对象上。
object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。
obj2=$.extend(true,[],obj1);