// 版本一
function deepclone(target) {JSON.parse(JSON.stringify(target));
}
/**弊端:会忽略undefined, symbol 和函数;NaN, Infinity, -Infinity 会被序列化为null;不能解决循环引用的问题
*/
// 版本二
function deepclone(target) {let cloneTarget = {} // 定义一个克隆对象Ï   for (const key in target) { cloneTarget[key] = target[key]}return cloneTarget
}/**弊端:对象并没有实现深拷贝
*/
// 版本三
function deepclone(target) {// 如果是原始类型,则直接返回if (typeof target !== 'object') {return target}// 如果是引用类型,则开始递归let cloneTarget = {} // 定义一个克隆对象
Ï   for (const key in target) { cloneTarget[key] = deepclone(target[key])}return cloneTarget
}/**弊端:数组,日期,正则,null没有处理
*/
// 版本四:
function deepclone(target) {// 处理nullif (target === null ) return target;// Dateif (target instanceof Date ) return new Date(target) // Regexpif (target instanceof RegExp ) return new RegExp(target) // 如果是原始类型,则直接返回if (typeof target !== 'object') {return target}// 如果是引用类型,则开始递归// let cloneTarget = {} // 定义一个克隆对象// 定义一个克隆对象 或者 克隆数组 根据原对象生成的let cloneTarget = new target.constructor()
Ï   for (const key in target) { cloneTarget[key] = deepclone(target[key])}return cloneTarget
}/**弊端:symbol()
*/
// 版本五
function deepclone(target) {// 处理nullif (target === null ) return target;// Dateif (target instanceof Date ) return new Date(target) // Regexpif (target instanceof RegExp ) return new RegExp(target) // 如果是原始类型,则直接返回if (typeof target !== 'object') {return target}// 如果是引用类型,则开始递归// let cloneTarget = {} // 定义一个克隆对象// 定义一个克隆对象 或者 克隆数组 根据原对象生成的let cloneTarget = new target.constructor()Reflect.ownKeys(target).forEach((key) => {cloneTarget[key] = deepclone(target[key])})return cloneTarget
}
/**弊端:无法处理循环引用
*/
// 版本六
// 额外开辟一个存储空间来存储当前对象和拷贝对象的对应关系function deepclone(target, hash = {}) {// 开始处理null regexp dateif (target == null) return target; // null// Dateif (target instanceof Date ) return new Date(target) // Regexpif (target instanceof RegExp ) return new RegExp(target) // 如果是原始类型,则无需继续拷贝,直接返回if (typeof target !== 'object') return target; // 原始类型// 为什么要这么写 不用在拷贝的时候去判断数组类型,// 原对象是数组,就创建一个新的克隆数组// 原对象是对象,就创建一个新的克隆对象if (hash[target]) {return hash[target]}// let cloneTarget = {} // 定义一个克隆对象// 创建一个新的克隆数组或者克隆对象let cloneTarget = new target.constructor() hash[target] = cloneTarget// for (const key in target) { //   // 开始递归//   cloneTarget[key] = deepclone(target[key])// }Reflect.ownKeys(target).forEach((key) => {cloneTarget[key] = deepclone(target[key], hash)})return cloneTarget}
// 版本七
// 配合垃圾回收机制,防止内存泄漏
function deepclone(target, hash = new WeakMap()) {// 开始处理null regexp dateif (target == null) return target; // null// Dateif (target instanceof Date ) return new Date(target)// Regexpif (target instanceof RegExp ) return new RegExp(target) // 如果是原始类型,则无需继续拷贝,直接返回if (typeof target !== 'object') return target; // 原始类型// 为什么要这么写 不用在拷贝的时候去判断数组类型,原对象是数组,就创建一个新的克隆数组// 原对象是对象,就创建一个新的克隆对象if (hash.get(target)) return hash.get(target)// let cloneTarget = {} // 定义一个克隆对象// 创建一个新的克隆数组或者克隆对象let cloneTarget = new target.constructor() hash.set(target, cloneTarget)Reflect.ownKeys(target).forEach((key) => {cloneTarget[key] = deepclone(target[key], hash)})return cloneTarget}

写在最后,浏览器其实有自己的深拷贝函数

let obj3 = structuredClone(obj);

JavaScript实现深拷贝相关推荐

  1. JavaScript对象深拷贝

    JavaScript对象深拷贝 引言 在JavaScript中对对象拷贝复制通常是使用循环遍历的方式: var obj = {x:1,y:[1,2,3] }var obj2 = {}; for(let ...

  2. 详解JavaScript对象深拷贝

    详解JavaScript对象深拷贝 在几乎所有编程语言中,对象都以引用形式保存给变量.复制给其他变量.JavaScript语言也是如此.因此简单的进行赋值操作进行复制仅仅是对对象数据的引用地址进行一个 ...

  3. javascript的深拷贝与浅拷贝

    本文对js中的浅拷贝与深拷贝做一个小结 两者区别如下: 深拷贝和浅拷贝是针对对象属性为对象的,因为基本数据类型在进行赋值操作时(也就是拷贝)是直接将值赋给了新的变量,也就是该变量是原变量的一个副本,这 ...

  4. 通俗易懂讲解JavaScript深拷贝和浅拷贝

    基本类型和引用类型 在开始讲解JavaScript的深拷贝和浅拷贝之前,先要认识JavaScript的两种基本数据类型.一种是基本类型(值类型),另外一种是引用类型.其中基本类型包括undefined ...

  5. javaScript深拷贝和浅拷贝简单梳理

    在了解深拷贝和浅拷贝之前,我们先梳理一下: JavaScript中,分为基本数据类型(原始值)和复杂类型(对象),同时它们各自的数据类型细分下又有好几种数据类型 基本数据类型 数字Number 字符串 ...

  6. JavaScript深拷贝的方法

    一.深拷贝和浅拷贝 基本数据类型: 字符串(string).数值(number).布尔值(boolean).undefined.null : 引用数据类型: 对象(Object).数组(Array). ...

  7. javascript深拷贝函数封装

    在javascript,python这种带引用类型的高级程序设计语言中,很容易出现浅拷贝而导致错误. 本篇文章,我浅述一下我对js中深拷贝函数封装的思考. 思路很简单,封装一个递归函数,终止条件是'不 ...

  8. JavaScript深拷贝(js深拷贝,JavaScript递归函数,实现深拷贝)

    简述:JavaScript的深拷贝和浅拷贝大家都比较熟悉,今天来分享下深拷贝,就是使用该函数时,会复制拷贝一份该数据,修改该数据属性,不会改变原有数据,就是把复制的对象所引用的对象全都复制了一遍,具体 ...

  9. javaScript笔记整理(一)

    目录 1.0如果想将JavaScript写到一对head标签中,并且需要在JavaScript代码中操作界面上的元素,就必须要加上: 2.0 JavaScript常用的输出方式 3.0JavaScri ...

最新文章

  1. 2022-2028年中国蛋白石行业发展现状分析及投资前景趋势报告
  2. 谷歌AI智商达苹果Siri两倍 但不及6岁儿童
  3. OLE和activex
  4. C/C++语言函数中参数的入栈顺序
  5. django settings 定义的变量不存在_使用Django部署机器学习模型(1)
  6. 《 图解 TCP/IP 》读书笔记
  7. 我必须要吐槽,你们的数据管理都是错的,这才是规划和产出
  8. php+js实现异步图片上传,JavaScript实现异步图像上传功能
  9. linux缓冲区攻击实验报告,linux 下缓冲区溢出攻击原理及示例
  10. 计算机中字符编码换算
  11. springboot整合ssm(mybatis)
  12. 捷径app 保存视频_Android N App捷径
  13. python importlib
  14. 南昌大学c语言程序设计,南昌大学C语言程序设计试卷C语言2.doc
  15. 【京东助手】滑稽东试用助手 V1.6.0
  16. 校园服务器虚拟机规划与设计,校园网服务器虚拟化技术的应用研究
  17. SwiftUI4 iOS16 新特性之 WeatherKit免费天气API使用教程(WWDC 2022教程含源码)
  18. ORACLE 11G使用exp或者pl/sql导出空表
  19. VB调用摄像头录像,拍照,保存
  20. 推荐几部不错的网络玄幻小说

热门文章

  1. 6月项目总结--浅尝jsp(官网优化),移动端Echarts,mescroll试水,树形插件bootstrap-treeview
  2. Android直播app
  3. android 蓝牙4.0 ble,Android 蓝牙4.0开启Notification 和 Indication
  4. linux系统下,nmon的安装及使用教程
  5. 博学和专一的一点小启示
  6. Deep Leaning 常用要点总结
  7. Freeswitch常见问题
  8. 2023年中高级Android面试题汇总(不断更新中)
  9. 检测到你的手机处于root环境_分享一下彻底清除手机病毒过程
  10. LPC546XX - USB -CDC-vcom(从机模式)串口自动关闭退出问题