1. JSON.parse(JSON.stringify()),工作当中使用比较多,但是存在一些问题,复杂的对象结构(内部包含function, Symbol, Map, Set的时候,无法实现深拷贝):
const obj = {
name: 'test',
fn: function(){
console.log(11)
},
[Symbol('a')]: 'aaa',
set: new Set([1, 2, 4, 5]),
map: new Map([
['name', '张三'],
['title', 'Author'],
]),
info: {
message: 'this is a message'
}
}
const cloneObject = JSON.parse(JSON.stringify(obj));
执行结果如下:
2.使用Object.defineProperties(newObj,Object.getOwnPropertyDescriptors(oldObj)),可以拷贝function, Symbol, Set, Map类型数据:
Object.defineProperties()
静态方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。
Object.getOwnPropertyDescriptors()
静态方法返回给定对象的所有自有属性描述符。
const oldObj = {
name: 'test',
fn: function(){
console.log(11)
},
[Symbol('a')]: 'aaa',
set: new Set([1, 2, 4, 5]),
map: new Map([
['name', '张三'],
['title', 'Author'],
]),
info: {
message: 'this is a message'
}
}
const newObj = {};
Object.defineProperties(newObj,Object.getOwnPropertyDescriptors(oldObj))
执行结果如下:
3. 手写递归函数
function deepCloneFn(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
let newObj;
if (Object.prototype.toString.call(obj) === '[object Object]') {
newObj = {};
Reflect.ownKeys(obj).forEach((ele) => {
newObj[ele] = deepCloneFn(obj[ele]);
});
} else if (Array.isArray(obj)) {
newObj = [];
for (let i = 0; i < obj.length; ++i) {
newObj.push(deepCloneFn(obj[i]));
}
} else if (Object.prototype.toString.call(obj) === '[object Set]') {
newObj = new Set([...obj]);
} else if (Object.prototype.toString.call(obj) === '[object Map]') {
newObj = new Map([...obj]);
}
return newObj;
}
4.Object.assign(target, source)只能拷贝一层数据结构,如果有嵌套层级,内部数据结构无法实现深拷贝