在 JavaScript 中,对象拷贝可以分为浅拷贝和深拷贝两种方式
1、浅拷贝
浅拷贝只是复制了对象的引用地址,新对象的属性与原对象的属性指向同一块内存地址
2、深拷贝
深拷贝会完整地复制对象以及其内部所有嵌套对象
使用 JSON.parse(JSON.stringify()) 方法进行深拷贝时,需要注意以下几点:
1、对象属性值只能是基本数据类型、数组或对象字面量,不能包含方法、正则表达式等特殊类型
2、对象中存在循环引用时会报错
1、实现对象的深度拷贝
function deepClone(obj, hash = new WeakMap()) {
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
if (typeof obj !== 'object' || obj === null) return obj;
if (hash.has(obj)) return hash.get(obj);
const clone = new obj.constructor();
hash.set(obj, clone);
for (let key in obj) {
if (obj.hasOwnProperty(key)) { // 处理自有属性
clone[key] = deepClone(obj[key], hash); // 如果是对象,则递归复制
}
}
return clone;
}
2、实现对象的深度对比
以下方法仅考虑了对象的可枚举属性,如果对象还包含不可枚举属性(例如通过 Object.defineProperty 方法定义的属性),则需要使用 Object.getOwnPropertyNames() 方法来获取所有属性名称,从而实现完整的深度对比。
function deepEqual(a, b) {
if (a === b) return true;
if (a instanceof Date && b instanceof Date) {
return a.getTime() === b.getTime();
}
if (a instanceof RegExp && b instanceof RegExp) {
return a.toString() === b.toString();
}
if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) {
return false;
}
const propsA = Object.getOwnPropertyNames(a);
const propsB = Object.getOwnPropertyNames(b);
if (propsA.length !== propsB.length) {
return false;
}
for (let i = 0; i < propsA.length; i++) {
const prop = propsA[i];
const isEqual = deepEqual(a[prop], b[prop]);
if (!isEqual) {
return false;
}
}
return true;
}
标签:instanceof,obj,对象,第七篇,深度,return,拷贝,属性
From: https://www.cnblogs.com/caix-1987/p/17308244.html