深拷贝的五种实现方式

news2025/2/24 13:36:49

一、什么是深拷贝和浅拷贝

  • 浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是指向内存的地址 ,所以如果其中一个对象改变了这个引用类型的值,就会影响到另一个对象
  • 深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象

二、实现深拷贝的五种方式

1、递归调用

// 递归调用
const deepCopy = (obj) => {
  // 判断传入的值是否为一个对象
  if (obj === null && typeof obj !== "object") {
    return obj;
  }
  // 判断对象的类型 注意这里不考虑包装类对象
  if (Object.prototype.toString.call(obj) === "[object Date]") {
    return new Date(obj);
  }
  if (Object.prototype.toString.call(obj) === "[object RegExp]") {
    return new RegExp(obj);
  }
  if (Object.prototype.toString.call(obj) === "[object Undefined]") {
    return new Error(obj);
  }
  // 判断对象是类
  let newObj = Array.isArray(obj)  ? [] : {}
  for(let item in obj){
    if(typeof obj[item] === 'object') {
        newObj[item] = deepCopy(obj[item])
    }else {
        newObj[item] = obj[item]
    }
  }
  return newObj
};

const foo = {
    name: '张三',
    info: {
        age: 24
    }
}
const newFoo = deepCopy(foo)
console.log(foo, newFoo)
foo.info.age = 25
console.log(foo, newFoo)

2、JSON.stringify + JSON.parse
:::info
更多关于JSON.stringigy的注意事项请看MDN
:::

// JSON.stringify
// 情况一: 对象内不存在undefined、symbol、function类型的属性时
// const foo = {
//     name: '张三',
//     info: {
//         age: 24
//     }
// }
// const newFoo = JSON.parse(JSON.stringify(foo))
// console.log(foo, newFoo) // { name: '张三', info: { age: 24 } } { name: '张三', info: { age: 24 } }
// foo.info.age = 25
// console.log(foo, newFoo) // { name: '张三', info: { age: 25 } } { name: '张三', info: { age: 24 } }

// 情况二:当对象内存在undefined、symbol、function类型的属性时,在序列化过程中会被忽略。
// 当属性为NaN 和 Infinity 格式的数值及 null 都会被当做 nul
// const foo = {
//   name: "张三",
//   age: undefined,
//   height: 183,
//   gender: Symbol("男"), //
//   say: () => {},
//   aa: NaN,
// };
// const newFoo = JSON.parse(JSON.stringify(foo));
// console.log(foo, newFoo); // {aa: NaN, age: undefined, gender: Symbol(男), height: 183, name: "张三"} { {name: '张三', height: 183, aa: null} }

// JSON.stringify() 第二个参数为可选参数,可以是一个函数或者数组,
// 当是数组时表示需要被转化的属性列表,但undeinfed,symbol,function类型的属性依然会被忽略

// const newFoo = JSON.parse(JSON.stringify(foo, ['name', 'age', 'gender', 'say', 'aa']));
// console.log(newFoo) // {name: '张三', aa: null}

3、lodash

const _ = require('lodash')
const foo = {
    name: '张三',
    info: {
        age: 24
    }
}
const newFoo = _.cloneDeep(foo);
foo.info.age = 25
console.log(foo, newFoo) // { name: '张三', info: { age: 25 } } { name: '张三', info: { age: 24 } }

4、Object.assgin

注意:只有当对象中没有嵌套对象时,才可以实现深拷贝
const foo = {
    name: '张三',
    age: 24
}
const newFoo = Object.assign({}, foo)
foo.age = 25
console.log(foo, newFoo) // {name: '张三', age: 25} {name: '张三', age: 24}

// 对象中有内嵌的对象时
const foo = {
    name: '张三',
    info: {
        age: 24
    }
}
const newFoo = Object.assign({}, foo)
foo.info.age = 25
console.log(foo, newFoo) // { name: '张三', info: { age: 25 } } { name: '张三', info: { age: 25 } }

5、structuredClone

const foo = {
    name: '张三',
    info: {
        age: 24
    }
}
const newFoo = structuredClone(foo) // 
foo.info.age = 25
console.log(foo, newFoo) // { name: '张三', info: { age: 25 } } { name: '张三', info: { age: 24 } }

该方法为Web最新的 API,存在兼容问题
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/405771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。

为了解决npm命令无法正常运行的问题 接上个博客 安装完新版node后使用npm命令会出现以下错误 大致意思就是识别不了npm命令是干啥的 解决方案: 1.首先确定是不是软件没有获得管理员权限运行,右键程序选择管理员权限运行 2.如果管理员权限运行后依然出现错误,检查node的配置…

React 框架

文章目录一、React 框架简介二、配置环境三、组件(Component)四、Component 组件的组合与交互一、React 框架简介 介绍 CS 与 BS结合:像 React,Vue 此类框架,转移了部分服务器的功能到客户端。将CS 和 BS 加以结合。客…

java简历项目经验案例(java简历项目经验怎么写)

如何描述项目经验-seo简历项目经验怎么?seo简历项目经验怎么写 写自己从事过的什么项目。写具体什么模块。如果没有就写自己能达到什么水平,能做出什么模块。 什么叫项目经验?什么叫项目经验?简历中的项目经验可以写些什么? 项目经验与工作…

flex布局之flex-direction

一、flex布局的原理 1,flex是”flexible Box”的缩写,意为”弹性布局”; 2.当我们为父盒子设为flex布局以后,子元素的float、clear和vertical-align属性将会失效。 言而简之:flex布局原理就是通过给父盒子添加flex属性&#xff0…

VUE项目部署

前端项目的部署 1.1 开发完的vue的项目 首先运行 以下命令 对项目进行打包 npm run build1.2 安装nginx服务器 ​ nginx是一款轻量级的Web服务器、反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛…

若依RuoYi-Vue前后端项目启动流程

1.git找到RuoYi-Vue RuoYi-Vue: 🎉 基于SpringBoot,Spring Security,JWT,Vue & Element 的前后端分离权限管理系统,同时提供了 Vue3 的版本 2.本地创建文件夹,cmd进入该文件夹下并进行克隆项目 git cl…

webpack安装与使用(详细)

一.什么是webpack? webpack是现代javascript应用程序的静态模块打包器,当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundl…

蓝桥杯第十四届蓝桥杯模拟赛第三期考场应对攻略(C/C++)

这里把我的想法和思路写出来,恳请批评指正! 目录 考前准备 试题1: 试题2: 试题3: 试题4: 试题5: 试题6: 试题7: 试题8: 试题9: 试题1…

Vue开发实例(05)之搭建项目主页面头部、导航、主体等页面布局

作者简介 作者名:编程界明世隐 简介:CSDN博客专家,从事软件开发多年,精通Java、JavaScript,博主也是从零开始一步步把学习成长、深知学习和积累的重要性,喜欢跟广大ADC一起打野升级,欢迎您关注&…

【Node.js实战】一文带你开发博客项目(API 对接 MySQL)

个人简介 👀个人主页: 前端杂货铺 🙋‍♂️学习方向: 主攻前端方向,也会涉及到服务端 📃个人状态: 在校大学生一枚,已拿多个前端 offer(秋招) 🚀未…

事件循环(Event Loop)

文章目录单线程事件循环机制(Event Loop)1、同步任务与异步任务同步任务异步任务宏任务微任务2、执行过程3、执行顺序4、举例:实例1实例2单线程 JavaScript是一种单线程的编程语言,同一时间只能做一件事,所有任务都需…

【Node.js实战】一文带你开发博客项目(MySQL基础)

个人简介 👀个人主页: 前端杂货铺 🙋‍♂️学习方向: 主攻前端方向,也会涉及到服务端 📃个人状态: 在校大学生一枚,已拿 offer(秋招) 🥇推荐学习&…

简单易懂 关于nextTick()的理解

前言 学习Vue的过程中,大家肯定都使用过nextTick(),关于nextTick()的使用时机,大家肯定都知道,那么它的工作原理是怎样的呢,本文就简单说一下它的nextTick()的工作原理。 nextTick的使用时机 首先记住:n…

vue中 router.beforeEach() 的用法

导航守卫 主要是通过跳转或取消得方式守卫导航 在前端路由跳转中,路由跳转前都是会经过beforeEach,而beforeEach可以通过next来控制到底去哪个路由。根据这个特性我们就可以在beforeEach中设置一些条件来控制路由的重定向。 常见的使用场景有&#xff1…

WordPress 中的常规设置

💂 个人网站:【海拥】【摸鱼游戏】【神级源码资源网站】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 想寻找共同学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】💬 免费且…

CSS实现背景图片模糊——毛玻璃效果 | 浅谈CSS属性 filter、backdrop-filter

💭💭 ✨: CSS实现背景图片模糊——毛玻璃效果 | 浅谈CSS属性 filter、backdrop-filter   💟:东非不开森的主页   💜: 因为很多东西来不及去做去看可是时间很快总是赶不上,所以要去成长呀&…

01-Node-Express系统框架搭建(express-generator)

文章目录一、使用express-generator创建项目1.1 安装express-generator模块1.2 生成express项目结构1.3 启动项目1.4 设置nodemon自启项目二、手动创建一个Express项目2.1 创建项目文件夹并初始化2.2 安装express模块2.3 创建项目主文件2.4 编辑app.js文件2.5 启动项目2.6 使用…

【CSS应用篇】——CSS如何实现渐变背景

目录 CSS 定义了两种渐变类型: 格式: 如何使用: ​编辑使用透明度: CSS 定义了两种渐变类型: 线性渐变(向下/向上/向左/向右/对角线);径向渐变(有中心向周围展开&am…

Vue--》MVVM模型在Vue中的使用

目录 理解MVVM模型 什么是 MVVM 模型 MVVM的组成部分 Vue中的实现 MVVM模型在 Vue 中的应用 理解MVVM模型 我们知道每一个 Vue 应用都是从创建一个新的实例开始的,根据 Vue2 的官方文档我们可以得知 Vue 的设计是得到了 MVVM 模型 的启发,所以就有…

Vue动态样式方法总结

Vue动态样式实现方式 前言 本文主要针对 Vue2.x 来展开vue的动态css样式方法归纳。 如果亲爱的读者们需要,后续会更新Vue3的动态样式方法或者使用TypeScript来实现。 CSS动态样式 一般用于设置某个字段根据状态显示不同的样式。 比如 字段A,平时返回0&am…