本文共 2644 字,大约阅读时间需要 8 分钟。
浅拷贝与深拷贝是 JavaScript 中常见的对象复制操作,它们的主要区别在于拷贝的深度。浅拷贝仅复制对象表面层的属性,包括对象自身的值,而不会深入复制嵌套的对象或数组。相比之下,深拷贝则会完全复制对象的所有层次,包括嵌套的对象、数组以及其他引用类型,使得修改后的对象与原对象完全无关。
浅拷贝的实现方法主要有以下几种:
function Clone(target) { if (typeof target !== 'object' || target === null) { return; } let newObject = target instanceof Array ? [] : {}; for (let prop in target) { if (target.hasOwnProperty(prop)) { newObject[prop] = target[prop]; } } return newObject;} 这个方法通过检查目标对象的类型,创建一个新对象,并逐一复制目标对象的自身属性。如果目标对象是数组,则创建一个新的数组;否则,创建一个空对象。然后遍历目标对象的属性,将每个属性值复制到新对象中。
Object.assign 实现浅拷贝Object.assign({}, target); Object.assign 方法可以将源对象的属性复制到目标对象中。使用 Object.assign 时,目标对象会被修改,而源对象保持不变。需要注意的是,如果目标对象已经存在属性,会被覆盖。
对于数组和对象,可以使用展开运算符(...)实现浅拷贝:
var newArr = [...targetArr]; // 拷贝数组var newObj = { ...targetObj }; // 拷贝对象 展开运算符会将数组或对象的所有可枚举属性复制到新对象中,实现了浅拷贝。
slice 实现数组浅拷贝var newArr = targetArr.slice();
slice 方法返回一个新数组,该新数组包含原数组的所有元素。修改新数组不会影响原数组。
concat 实现数组浅拷贝var newArr = targetArr.concat();
concat 方法创建一个新数组,包含原数组的所有元素。与 slice 类似,修改新数组不会影响原数组。
深拷贝的目标是创建一个完全独立的新对象,使得修改新对象不会影响原对象。实现深拷贝的方法主要有以下几种:
function deepClone(target) { if (typeof target !== 'object' || target === null) { return; } let newObject = target instanceof Array ? [] : {}; for (let prop in target) { if (target.hasOwnProperty(prop)) { newObject[prop] = typeof target[prop] === 'object' ? deepClone(target[prop]) : target[prop]; } } return newObject;} 这个方法通过递归调用 deepClone 方法,逐层复制对象的属性。如果属性值是对象或数组,则继续递归拷贝;否则,直接复制值。
JSON.stringify 方法实现深拷贝var clonedObject = JSON.parse(JSON.stringify(target));
JSON.stringify 方法可以将对象序列化为字符串,然后再反序列化为新对象。这种方法适用于大多数对象类型,但不能拷贝 Date、RegExp 等内置对象。
const isObject = (target) => (typeof target === "object" || typeof target === "function") && target !== null;function deepClone(target, map = new WeakMap()) { if (map.has(target)) { return target; } const constructor = target.constructor; if (/^(RegExp|Date)$/i.test(constructor.name)) { return new constructor(target); } if (isObject(target)) { map.set(target, true); const cloneTarget = Array.isArray(target) ? [] : {}; for (let prop in target) { if (target.hasOwnProperty(prop)) { cloneTarget[prop] = deepClone(target[prop], map); } } return cloneTarget; } else { return target; }} 这个方法基于简单版深拷贝的基础上,进一步处理了内置对象(如 Date、RegExp)和循环引用问题。通过 WeakMap 记录对象引用,确保循环引用对象不会被错误拷贝。
浅拷贝和深拷贝是 JavaScript 中常用的操作方式。浅拷贝适用于不需要深入复制嵌套对象的场景,而深拷贝则用于确保拷贝的对象完全独立。选择合适的拷贝方法取决于具体需求和对象复杂度。
转载地址:http://qqln.baihongyu.com/