首页 > web前端 > js教程 > 正文

js怎样实现深拷贝

煙雲
发布: 2025-08-07 09:16:01
原创
916人浏览过

深拷贝是指创建一个与原对象完全独立的新对象,修改新对象不会影响原对象。1. 实现深拷贝的方法有多种,最简单的是json.parse(json.stringify(obj)),但其无法处理函数、undefined、symbol及循环引用。2. 更可靠的深拷贝需使用递归配合weakmap缓存已拷贝对象,避免循环引用导致的栈溢出。3. 函数无法真正深拷贝,通常只能复制引用,通过闭包或this绑定实现行为一致。4. 性能方面,深拷贝耗时耗资源,应根据对象复杂度选择合适方法,简单对象可用json方法,复杂对象推荐递归或第三方库如lodash的_.clonedeep()。5. 应用场景上,浅拷贝适用于仅需复制引用的场景,如react状态更新;深拷贝适用于需完全隔离数据的场景,如数据备份、防止原始数据被篡改等。因此,选择深拷贝还是浅拷贝应基于具体需求权衡性能与安全性。

js怎样实现深拷贝

深拷贝,简单来说,就是创建一个新对象,这个新对象和原始对象完全独立,修改新对象不会影响到原始对象。这和浅拷贝不同,浅拷贝只是复制对象的引用,修改拷贝后的对象会影响到原始对象。

js怎样实现深拷贝

解决方案

JavaScript实现深拷贝,方法有很多,各有优劣。最简单粗暴的就是

JSON.parse(JSON.stringify(obj))
登录后复制
,但这种方法有局限性,比如不能拷贝函数、
undefined
登录后复制
Symbol
登录后复制
等特殊类型,而且如果对象中存在循环引用,还会报错。

js怎样实现深拷贝

更健壮的深拷贝实现需要递归遍历对象,并对不同类型的值进行特殊处理。

function deepCopy(obj, cache = new WeakMap()) {
  // 处理 null 和 undefined
  if (obj === null || typeof obj !== "object") {
    return obj;
  }

  // 处理循环引用
  if (cache.has(obj)) {
    return cache.get(obj);
  }

  let copy;
  if (Array.isArray(obj)) {
    copy = [];
  } else {
    copy = {};
  }

  cache.set(obj, copy);

  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepCopy(obj[key], cache);
    }
  }

  return copy;
}

// 示例
const obj = {
  name: "Alice",
  age: 30,
  address: {
    city: "New York",
    zip: 10001,
  },
  hobbies: ["reading", "coding"],
  greet: function() {
    console.log("Hello!");
  },
  symbol: Symbol('test'),
  undef: undefined
};

obj.circular = obj; // 创建循环引用

const newObj = deepCopy(obj);

newObj.name = "Bob";
newObj.address.city = "Los Angeles";
newObj.hobbies.push("hiking");

console.log("Original object:", obj);
console.log("Copied object:", newObj);
登录后复制

这个

deepCopy
登录后复制
函数使用递归的方式遍历对象,并且用
WeakMap
登录后复制
来缓存已经拷贝过的对象,防止循环引用导致栈溢出。 注意,函数和
Symbol
登录后复制
类型的值不会被拷贝,会丢失。
undefined
登录后复制
会被保留。

js怎样实现深拷贝

如何处理函数类型的深拷贝?

理论上,完全深拷贝函数是不可行的,因为函数内部的状态是无法完全复制的。但是,可以考虑复制函数的引用,或者创建一个新的函数,并复制原始函数的代码。 复制函数代码涉及到解析和重构函数的抽象语法树 (AST),比较复杂,一般不推荐。 大多数情况下,复制函数引用就足够了。

function deepCopyWithFunction(obj, cache = new WeakMap()) {
    if (obj === null || typeof obj !== "object") {
        return obj;
    }

    if (cache.has(obj)) {
        return cache.get(obj);
    }

    let copy;
    if (Array.isArray(obj)) {
        copy = [];
    } else if (typeof obj === 'function') {
        // 复制函数引用
        copy = obj;
        return copy;
    }
    else {
        copy = {};
    }

    cache.set(obj, copy);

    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            copy[key] = deepCopyWithFunction(obj[key], cache);
        }
    }

    return copy;
}

const objWithFunction = {
    name: "Alice",
    greet: function() {
        console.log("Hello, " + this.name);
    }
};

const newObjWithFunction = deepCopyWithFunction(objWithFunction);
newObjWithFunction.name = "Bob";
newObjWithFunction.greet(); // 输出 "Hello, Bob"

objWithFunction.greet(); // 输出 "Hello, Alice"
登录后复制

这种方法仅仅复制了函数的引用,所以

newObjWithFunction.greet()
登录后复制
中的
this.name
登录后复制
会指向
newObjWithFunction
登录后复制
name
登录后复制
属性。

NovelAI
NovelAI

AI 辅助写作、讲故事,基于你自己的作品创造出类似人类的写作。

NovelAI 236
查看详情 NovelAI

深拷贝的性能考量有哪些?

深拷贝是一个相对耗时的操作,特别是对于大型对象。 递归遍历和创建新对象都需要消耗大量的CPU和内存。

JSON.parse(JSON.stringify(obj))
登录后复制
在处理大型对象时,效率也比较低。

在实际应用中,需要根据对象的复杂度和性能要求,选择合适的深拷贝方法。 如果对象比较简单,且不需要拷贝函数等特殊类型,

JSON.parse(JSON.stringify(obj))
登录后复制
是一个不错的选择。 如果对象比较复杂,且需要处理循环引用,那么就需要使用递归的方式实现深拷贝。

还可以考虑使用一些第三方库,比如Lodash的

_.cloneDeep()
登录后复制
方法,它提供了更完善的深拷贝实现,并且经过了性能优化。

深拷贝和浅拷贝的应用场景分别是什么?

浅拷贝通常用于只需要复制对象的引用,而不需要创建新对象的场景。 比如,在React中,可以使用浅拷贝来更新组件的状态,如果状态对象中的某个属性发生了变化,只需要创建一个新的状态对象,并复制其他属性的引用即可。

深拷贝则用于需要创建完全独立的对象副本的场景。 比如,在处理用户输入的数据时,可以使用深拷贝来防止恶意用户修改原始数据。 又或者,在进行数据持久化时,可以使用深拷贝来创建数据的备份,防止数据丢失

以上就是js怎样实现深拷贝的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号