博客
关于我
浅拷贝与深拷贝
阅读量:209 次
发布时间:2019-02-28

本文共 2644 字,大约阅读时间需要 8 分钟。

浅拷贝与深拷贝是 JavaScript 中常见的对象复制操作,它们的主要区别在于拷贝的深度。浅拷贝仅复制对象表面层的属性,包括对象自身的值,而不会深入复制嵌套的对象或数组。相比之下,深拷贝则会完全复制对象的所有层次,包括嵌套的对象、数组以及其他引用类型,使得修改后的对象与原对象完全无关。


浅拷贝

浅拷贝的实现方法主要有以下几种:

1. 手写浅拷贝

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;}

这个方法通过检查目标对象的类型,创建一个新对象,并逐一复制目标对象的自身属性。如果目标对象是数组,则创建一个新的数组;否则,创建一个空对象。然后遍历目标对象的属性,将每个属性值复制到新对象中。

2. 使用 Object.assign 实现浅拷贝

Object.assign({}, target);

Object.assign 方法可以将源对象的属性复制到目标对象中。使用 Object.assign 时,目标对象会被修改,而源对象保持不变。需要注意的是,如果目标对象已经存在属性,会被覆盖。

3. 使用展开运算符

对于数组和对象,可以使用展开运算符(...)实现浅拷贝:

var newArr = [...targetArr]; // 拷贝数组var newObj = { ...targetObj }; // 拷贝对象

展开运算符会将数组或对象的所有可枚举属性复制到新对象中,实现了浅拷贝。

4. 使用 slice 实现数组浅拷贝

var newArr = targetArr.slice();

slice 方法返回一个新数组,该新数组包含原数组的所有元素。修改新数组不会影响原数组。

5. 使用 concat 实现数组浅拷贝

var newArr = targetArr.concat();

concat 方法创建一个新数组,包含原数组的所有元素。与 slice 类似,修改新数组不会影响原数组。


深拷贝

深拷贝的目标是创建一个完全独立的新对象,使得修改新对象不会影响原对象。实现深拷贝的方法主要有以下几种:

1. 手写简单版深拷贝

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 方法,逐层复制对象的属性。如果属性值是对象或数组,则继续递归拷贝;否则,直接复制值。

2. 使用 JSON.stringify 方法实现深拷贝

var clonedObject = JSON.parse(JSON.stringify(target));

JSON.stringify 方法可以将对象序列化为字符串,然后再反序列化为新对象。这种方法适用于大多数对象类型,但不能拷贝 DateRegExp 等内置对象。

3. 复杂版深克隆

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;    }}

这个方法基于简单版深拷贝的基础上,进一步处理了内置对象(如 DateRegExp)和循环引用问题。通过 WeakMap 记录对象引用,确保循环引用对象不会被错误拷贝。


总结

浅拷贝和深拷贝是 JavaScript 中常用的操作方式。浅拷贝适用于不需要深入复制嵌套对象的场景,而深拷贝则用于确保拷贝的对象完全独立。选择合适的拷贝方法取决于具体需求和对象复杂度。

转载地址:http://qqln.baihongyu.com/

你可能感兴趣的文章
Objective-C实现finding bridges寻找桥梁算法(附完整源码)
查看>>
Objective-C实现first come first served先到先得算法(附完整源码)
查看>>
Objective-C实现Gale-Shapley盖尔-沙普利算法(附完整源码)
查看>>
Objective-C实现getline函数功能(附完整源码)
查看>>
Objective-C实现gnome sortt侏儒排序算法(附完整源码)
查看>>
Objective-C实现greatest common divisor最大公约数算法(附完整源码)
查看>>
Objective-C实现greedy coin change贪心硬币找零算法(附完整源码)
查看>>
Objective-C实现half adder半加器算法(附完整源码)
查看>>
Objective-C实现hamiltonianCycle哈密尔顿图算法(附完整源码)
查看>>
Objective-C实现hamming code汉明码算法(附完整源码)
查看>>
Objective-C实现hamming numbers汉明数算法(附完整源码)
查看>>
Objective-C实现hammingDistance汉明距离算法(附完整源码)
查看>>
Objective-C实现hanning 窗(附完整源码)
查看>>
Objective-C实现hanoiTower汉诺塔算法(附完整源码)
查看>>
Objective-C实现hardy ramanujana定理算法(附完整源码)
查看>>
Objective-C实现harmonic series调和级数算法(附完整源码)
查看>>
Objective-C实现harris算法(附完整源码)
查看>>
Objective-C实现HashTable哈希表算法(附完整源码)
查看>>
Objective-C实现haversine distance斜距算法(附完整源码)
查看>>
Objective-C实现heap sort堆排序算法(附完整源码)
查看>>