js深拷贝对象

时间:2021-05-22 19:54:16

浅拷贝和深拷贝的区别

浅拷贝:只拷贝对象的基础属性值,对属性值为对象或数组的属性则拷贝指针。
深拷贝:拷贝对象的所有属性作为一个全新的对象。拷贝前后的对象互不影响。

浅拷贝

var a = {name:"test",children:{name:"test1"}}
//浅拷贝
var b = {
name:a.name,
children:a.children
}
a.name = "字面量属性拷贝"
a.children.name = "浅拷贝"
console.log(a)//Object {name: "字面量属性拷贝", children: Object{name:"浅拷贝"}}
console.log(b)//Object {name: "test", children: Object{name:"浅拷贝"}}

可以看出浅拷贝只拷贝了对象的基础属性值,对对象或数组的属性值则是只是拷贝了引用。所以修改a.name的时候,由于name的属性值为字符串所以直接拷贝了,a的修改不影响b。当修改a.children属性的时候,由于该属性值是个对象,所以b只拷贝了引用,故b.children也变化了

深拷贝

var a = {name:"test",children:{name:"test1"}}
//深拷贝
var b = {
name:a.name,
children:{name:a.children.name}
}
a.name = "字面量属性拷贝"
a.children.name = "浅拷贝"
console.log(a)//Object {name: "字面量属性拷贝", children: Object{name:"浅拷贝"}}
console.log(b)//Object {name: "test", children: Object{name:"test1"}}

深拷贝是对浅拷贝的进一步解析,直到所有的属性都为基础属性值为止,所以深拷贝的对象是完全独立的一个新对象。

深拷贝公共方法封装

/* ================ 深拷贝 ================ */
//返回传递给他的任意对象的类
const isClass = (o) => {
if (o === null) return "Null";
if (o === undefined) return "Undefined";
return Object.prototype.toString.call(o).slice(8, -1);
}

//深度克隆
const deepClone = (obj) => {
let result, oClass = isClass(obj);
//确定result的类型
if (oClass === "Object") {
result = {};
} else if (oClass === "Array") {
result = [];
} else {
return obj;
}

for (let key in obj) {
let copy = obj[key];
if (isClass(copy) == "Object") {
result[key] = deepClone(copy);//递归调用
} else if (isClass(copy) == "Array") {
result[key] = deepClone(copy);
} else {
result[key] = obj[key];
}
}
return result;
}

Object.assign()

特别注意:ES6提供了一个Object.assign()方法用于拷贝和合并对象,但是该方法也只是一个浅拷贝方法,使用时请慎重。