当前位置: 首页 > news >正文

js-17-对数组、对象进行浅拷贝和深拷贝

目录

  • 数组
    • 一、浅拷贝
      • 1. 展开运算符...
      • 2. Array.prototype.slice()
    • 二、深拷贝
      • 1. JSON方法
      • 2. 递归函数
  • 对象
    • 一、浅拷贝
      • 1. Object.assign()
      • 2. 展开运算符...
    • 二、深拷贝
      • 1. JSON方法
      • 2. 递归函数

自己总结的一些方法,可能有不到位的地方,欢迎指出

数组

一、浅拷贝

1. 展开运算符…

let arr1 = [1,2,'3',true, { name: '李华'}]
let arr2 = [...arr1] // arr2=[1,2,'3',true, { name: '李华'}]arr2[0] = 0 // 修改浅拷贝数组中的基本类型元素,原始数组不受影响
arr2[3] = false // 修改浅拷贝数组中的基本类型元素,原始数组不受影响
arr2[4].name = '小帅' // 修改浅拷贝数组中的对象的属性,由于对象是引用类型,所以原始数组中的对象也会受到影响console.log(arr1) // [1,2,'3',true, { name: '小帅'}]
console.log(arr2) // [0,2,'3',false,{ name: '小帅'}]

2. Array.prototype.slice()

let arr1 = [1, 2, '3', true, { name: '李华'}]
let arr2 = arr1.slice() // arr2=[1,2,'3',true,{ name: '李华'}]arr2[0] = 0
arr2[3] = false
arr2[4].name = '小帅'console.log(arr1) // [1, 2, '3', true, { name: '小帅' }]
console.log(arr2) // [0, 2, '3', false, { name: '小帅' }]

二、深拷贝

1. JSON方法

注意:此方法不能处理函数、undefined、Symbol和循环引用

    let arr1 = [1, 2, '3', true, { name: '李华'}]let arr2 = JSON.parse(JSON.stringify(arr1))arr2[0] = 0arr2[3] = falsearr2[4].name = '小帅'console.log(arr1) // [1, 2, '3', true, { name: '李华'}]console.log(arr2) // [0, 2, '3', false, { name: '小帅'}]

2. 递归函数

    function deepClone(obj, hash = new WeakMap()) {if (obj === null) return nullif (obj instanceof Date) return new Date(obj) // 如果是日期对象,则直接返回一个新的日期对象if (obj instanceof RegExp) return new RegExp(obj) // 如果是正则对象,则直接返回一个新的正则对象// 如果循环引用了就用 weakMap 来解决  if (hash.has(obj)) return hash.get(obj);let allDesc = Object.getOwnPropertyDescriptors(obj);let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc);hash.set(obj, cloneObj);for (let key of Reflect.ownKeys(obj)) {if (typeof obj[key] === 'object' && obj[key] !== null) {cloneObj[key] = deepClone(obj[key], hash); // 递归复制  } else {cloneObj[key] = obj[key];}}return cloneObj;}let arr1 = [1, 2, '3', true, { name: '李华' }, undefined]let arr2 = deepClone(arr1)arr2[4].name = '小帅'console.log(arr1) // [1, 2, '3', true, { name: '李华' }, undefined]console.log(arr2) // [1, 2, '3', true, { name: '小帅' }, undefined]

对象

一、浅拷贝

1. Object.assign()

    let obj1 = {a: 1, b: {c: 2}}let obj2 = Object.assign({}, obj1) // obj2={a:1, b: {c:2}}obj2.a = 100obj2.b.c = 200console.log(obj1) // { a: 1, b: { c: 200 } }console.log(obj2) // { a: 100, b: { c: 200 } }

2. 展开运算符…

    let obj1 = {a: 1, b: {c: 2}}let obj2 = {...obj1}obj2.a = 100obj2.b.c = 200console.log(obj1) // { a: 1, b: { c: 200 } }console.log(obj2) // { a: 100, b: { c: 200 } }

二、深拷贝

1. JSON方法

    let obj1 = {a: 1,b: {c: 2},d: [3, 4],e: undefined, // 注意此方法undefined不会被复制f: function(){ console.log('Hello world')} // 注意此方法函数不会被复制}let obj2 = JSON.parse(JSON.stringify(obj1))// console.log(obj2) // {a:1, b: {c:2}, d: [3,4]}obj2.b.c = 200obj2.d[0] = 300console.log(obj1) // { a: 1, b: { c: 2 }, d: [3, 4], e: undefined, f: f()}console.log(obj2) // { a: 1, b: { c: 200 }, d: [300, 4] }

2. 递归函数

    function deepClone(obj, hash = new WeakMap()) {// 处理基本数据类型和null  if (obj === null || typeof obj !== 'object') {return obj;}// 处理日期和正则对象  if (obj instanceof Date) {return new Date(obj);}if (obj instanceof RegExp) {return new RegExp(obj);}// 如果已经处理过这个对象,则直接返回缓存的结果  if (hash.has(obj)) {return hash.get(obj);}// 根据obj的类型创建一个新的对象或数组  let cloneObj = Array.isArray(obj) ? [] : {};hash.set(obj, cloneObj); // 将原始对象和克隆对象存储在hash中,以处理循环引用  // 递归复制对象的每个属性  for (let key in obj) {if (obj.hasOwnProperty(key)) {cloneObj[key] = deepClone(obj[key], hash);}}// 如果obj是Map或Set,则需要特殊处理  if (obj instanceof Map) {cloneObj = new Map();obj.forEach((value, key) => {cloneObj.set(deepClone(key, hash), deepClone(value, hash));});} else if (obj instanceof Set) {cloneObj = new Set();obj.forEach(value => {cloneObj.add(deepClone(value, hash));});}return cloneObj;}let obj1 = {a: 1,b: {c: 2},d: [3, 4],e: undefined, // 注意此方法undefined不会被复制f: function () { console.log('Hello world') } // 注意此方法函数不会被复制,而且其实通常不深拷贝函数}let obj2 = deepClone(obj1)// console.log(obj2) // { a: 1, b: { c: 2 }, d:[3, 4], e:undefined, f:f()}obj2.b.c = 200obj2.d[0] = 300console.log(obj1) // { a: 1, b: { c: 2 }, d: [3, 4], e: undefined, f: f()}console.log(obj2) // { a: 1, b: { c: 200 }, d: [300, 4], e: undefined, f: f() }
http://www.lryc.cn/news/446735.html

相关文章:

  • Ubuntu24.04中安装Electron
  • CPU中也应用到了缓存:CPU3层高速缓存,以及它的缓存一致性问题、MESI协议和Java的一些应用
  • 如何使用开发者工具捕获鼠标右键点击事件
  • 【几何】个人练习-Leetcode-1453. Maximum Number of Darts Inside of a Circular Dartboard
  • 啤酒:从饮品到文化的演变
  • Java 中 Map 常用类和数据结构详解
  • 实时监控,动态调整 —— 淘宝商品详情API助力商家实现灵活经营
  • WebGL常用接口和事件
  • Golang | Leetcode Golang题解之第429题N叉树的层序遍历
  • 数据库的全透明加密和半透明加密主要是针对数据存储安全的不同处理方式
  • MySQL的登录、访问、退出
  • 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-25
  • PyTorch框架安装
  • 分布式锁优化之 使用lua脚本改造分布式锁保证判断和删除的原子性(优化之LUA脚本保证删除的原子性)
  • 从安防视频监控行业发展趋势看EasyCVR平台如何驱动行业智能升级
  • TIOBE 编程指数 9 月排行榜公布 VB.Net第七
  • 如何用ChatGPT制作一款手机游戏应用
  • 0基础学前端 day4
  • 功能测试详解
  • <Java>String类型变量的使用
  • JavaScript可视化
  • HTML5简介的水果蔬菜在线商城网站源码系列模板3
  • 传输层TCP协议
  • 自己开发一个网站系列之-网页开发初识
  • 【代码随想录训练营第42期 Day61打卡 - 图论Part11 - Floyd 算法与A * 算法
  • docker和ufw冲突问题
  • Java(基本数据类型)( ̄︶ ̄)↗
  • 283. 移动0
  • Mysql删库跑路,如何恢复数据?
  • 【HarmonyOS】应用引用media中的字符串资源如何拼接字符串