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

Javascript Object.assgin()详解以及深浅拷贝

Object.assign() 方法是 JavaScript 中用于将所有可枚举属性的值从一个或多个源对象复制到目标对象的方法。它将返回目标对象。这是一种浅拷贝,也就是说,如果源对象中的属性是一个对象或数组,那么这个属性的引用将被复制,而不是对象的深层次拷贝。
语法
javascript
Object.assign(target, ...sources)
target: 目标对象,所有源对象的属性将被复制到这个对象上。
sources: 源对象,其可枚举属性会被复制到目标对象。
示例
基本用法
javascript
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source);

console.log(target);        // { a: 1, b: 4, c: 5 }
console.log(returnedTarget); // { a: 1, b: 4, c: 5 },与target相同,因为返回的就是target
对象属性的覆盖
如果目标对象与源对象中有同名属性,源对象的属性值会覆盖目标对象的属性值。
javascript
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

Object.assign(target, source);
console.log(target.b); // 4,被source中的b覆盖了
多个源对象
可以从多个源对象中复制属性到目标对象,后面的源对象属性会覆盖前面的同名属性。
javascript
const target = { a: 1, b: 2 };
const source1 = { b: 4, c: 5 };
const source2 = { c: 6, d: 7 };

Object.assign(target, source1, source2);
console.log(target); // { a: 1, b: 4, c: 6, d: 7 }
浅拷贝
Object.assign() 只会进行浅拷贝,如果源对象的属性是引用类型(如对象或数组),那么复制的是引用,不是值。
javascript
const target = {};
const source = { a: { b: 2 } };

Object.assign(target, source);
console.log(target.a === source.a); // true,说明复制的是引用
避免覆盖目标对象原有属性
如果你不想改变目标对象,可以先用空对象作为目标对象,然后将结果赋值给新的变量。
javascript
const source = { a: 1, b: 2 };
const targetCopy = Object.assign({}, source);

console.log(targetCopy); // { a: 1, b: 2 }
注意事项
Object.assign() 不会复制源对象的不可枚举属性。
Object.assign() 也不会复制对象上的属性描述符(如 writable, enumerable, configurable)。
对于值为 null 或 undefined 的源对象,Object.assign() 不会抛出错误,但也不会进行任何复制操作。
使用 Object.assign() 可以在需要合并对象或复制对象属性时非常有用,但了解其浅拷贝的特性以及如何处理引用类型的属性是很重要的。

 

JavaScript中的深拷贝是一个常见但重要的概念,它指的是创建一个新的对象,这个新对象与原始对象完全独立,拥有自己独立的内存地址,修改新对象不会影响原始对象。下面是对JavaScript深拷贝的详细解析:
一、深拷贝与浅拷贝的区别
浅拷贝:只复制对象的第一层属性,如果属性是基本类型,则复制其值;如果属性是引用类型(如对象、数组),则复制其引用地址,即新旧对象共享同一个引用。
深拷贝:不仅复制对象的第一层属性,还递归地复制对象的所有嵌套属性,生成一个新的、完全独立的对象副本。
二、深拷贝的必要性
深拷贝在需要确保对象独立性、避免数据共享和意外修改的场景中尤为重要。例如,在状态管理、数据处理和表单数据处理等场景中,深拷贝能确保数据的完整性和安全性。
三、深拷贝的常见方法
JSON.parse(JSON.stringify(obj))
这是实现深拷贝的一种简单方法,通过将对象序列化为JSON字符串,然后再解析这个字符串得到一个新的对象。这种方法简单易用,但存在局限性,如无法处理函数、undefined、Symbol等特殊类型,也无法拷贝对象的原型链和循环引用对象。
递归实现深拷贝
通过递归遍历对象,对每个属性进行深拷贝。这种方法能够处理各种复杂的数据结构,但需要手动处理循环引用等特殊情况。
示例代码:
javascript
   function deepClone(obj, hash = new WeakMap()) {
       if (typeof obj !== 'object' || obj === null) {
           return obj;
       }
       if (hash.has(obj)) {
           return hash.get(obj);
       }
       const target = Array.isArray(obj) ? [] : {};
       hash.set(obj, target);
       Reflect.ownKeys(obj).forEach(key => {
           const val = obj[key];
           if (typeof val === 'object' && val !== null) {
               target[key] = deepClone(val, hash);
           } else {
               target[key] = val;
           }
       });
       return target;
   }
   
使用Lodash的cloneDeep方法
Lodash是一个非常流行的JavaScript工具库,其中的cloneDeep函数提供了强大的深拷贝功能,能够处理对象中的大多数复杂情况,包括循环引用。使用这种方法需要引入Lodash库。
示例代码:
javascript
   const _ = require('lodash');
   let obj1 = {name: "Alice", info: {age: 25}};
   let obj2 = _.cloneDeep(obj1);
   obj2.info.age = 30;
   console.log(obj1.info.age); // 输出: 25
   
使用structuredClone方法
structuredClone是一个新的API,它使用结构化克隆算法来实现深拷贝。该算法能够处理大多数复杂数据结构,如日期、正则表达式、循环引用等。不过,需要注意的是,较旧的浏览器版本可能不支持此方法。
示例代码:
javascript
   let obj1 = {name: "Alice", date: new Date(), info: {age: 25}};
   let obj2 = structuredClone(obj1);
   obj2.info.age = 30;
   console.log(obj1.info.age); // 输出: 25
   
四、注意事项
在使用深拷贝时,需要根据实际场景和数据结构选择合适的方法。
对于包含循环引用的对象,简单的递归方法可能无法正常工作,此时应考虑使用Lodash的cloneDeep或structuredClone方法。
深拷贝可能会增加程序的复杂性和性能开销,特别是在处理非常大的对象时,因此应谨慎使用。
综上所述,JavaScript中的深拷贝是一个重要的概念,掌握多种深拷贝方法对于开发高质量的应用程序至关重要。

相关文章:

Javascript Object.assgin()详解以及深浅拷贝

Object.assign() 方法是 JavaScript 中用于将所有可枚举属性的值从一个或多个源对象复制到目标对象的方法。它将返回目标对象。这是一种浅拷贝,也就是说,如果源对象中的属性是一个对象或数组,那么这个属性的引用将被复制,而不是对…...

Redis篇(应用案例 - UV统计)(持续更新迭代)

目录 一、HyperLogLog 二、测试百万数据的统计 一、HyperLogLog 首先我们搞懂两个概念: UV:全称Unique Visitor,也叫独立访客量,是指通过互联网访问、浏览这个网页的自然人。 1天内同一个用户多次访问该网站,只记录…...

解锁微信小程序新技能:ECharts动态折线图搭配WebSocket,数据刷新快人一步!

在微信小程序中,数据可视化展示越来越受到开发者的重视。本文将为您介绍如何在微信小程序中使用ECharts绘制折线图,并通过WebSocket实现实时更新图表数据。 一、准备工作 创建微信小程序项目 首先,我们需要创建一个微信小程序项目。如果您已…...

上交所服务器崩溃:金融交易背后的技术隐患暴露杭州BGP高防服务器43.228.71.X

一、上交所宕机事件始末 2024 年 9 月 27 日,上交所交易系统突发崩溃,这一事件犹如一颗巨石投入平静的湖面,引起了轩然大波。当天上午,众多投资者反馈券商交易出现延迟问题,随后上交所发布了《关于股票竞价交易出现异常…...

P4、P4D、HelixSwarm 各种技术问题咨询

多年大型项目P4仓库运维经验,为你解决各种部署以及标准工业化流程问题。 Perforce 官网SDPHelixCore GuideHelixSwarm GuideHelixSwarm Download...

Linux 应用层协议HTTP

文章目录 一、初始HTTP协议二、URL格式网络中怎么通过URL进行定位资源呢?编码和解码 三、HTTP的请求格式和响应格式HTTP的请求格式HTTP的响应格式HTTP的请求方法GET方法POST方法GET Vs PostHTTP的封装和分用文件流操作浏览器获得一个完整的网页流程 HTTP的状态码对3…...

Python和C++混淆矩阵地理学医学物理学视觉语言模型和算法模型评估工具

🎯要点 优化损失函数评估指标海岸线检测算法评估遥感视觉表征和文本增强乳腺癌预测模型算法液体中闪烁光和切伦科夫光分离多标签分类任务性能评估有向无环图、多路径标记和非强制叶节点预测二元分类评估特征归因可信性评估马修斯相关系数对比其他准确度 Python桑…...

HTTP 协议的基本格式和 fiddler 的用法

HTTP协议格式 HTTP是⼀个⽂本格式的协议.可以通过Chrome开发者⼯具或者Fiddler抓包,分析HTTP请求/响应的细节. 抓包工具的使用 以Fiddler为例. • 左侧窗⼝显⽰了所有的HTTP请求/响应,可以选中某个请求查看详情. • 右侧上⽅显⽰了HTTP请求的报⽂内容.(切换到Raw标签⻚可以看…...

【计算机网络】详解UDP协议格式特点缓冲区

一、UDP 协议端格式 16 位 UDP 长度, 表示整个数据报(UDP 首部UDP 数据)的最大长度;如果16位UDP检验和出错,报文会被直接丢弃。 1.1、检验和出错的几种常见情况 数据传输过程中的比特翻转:在数据传输过程中,由于物理介质或网络设…...

网络安全cybersecurity的几个新领域

一、电力安全 同学们,今天我们来讨论一下为什么网络安全(Cybersecurity)和电力系统(Power Systems)这两个看似不同的领域会有交集。其实,这两个领域之间的联系非常紧密。以下我将从多个角度进行解释&#…...

android 原生加载pdf

implementation("androidx.pdf:pdf-viewer-fragment:1.0.0-alpha02") pdf加载链接...

MAE(平均绝对误差)和std(标准差)计算中需要注意的问题

一、MAE(平均绝对误差) 计算公式: yi​ 是第i个实际值y^​i​ 是第i个预测值 计算方法: MAE就是求实际值与预测值之间的误差,需要给出预测值和原始的实际值 二、std(标准差) 计算公式&#x…...

03实战篇:把握667分析题的阅读材料、题目

本节你将学习到: 如何快速识别阅读材料的有效信息如何把握题目的作答方向 在正式进入具体的实战之前,我想先来讲一讲如何利用给定阅读材料、如何分析题目来确保不偏题等基础性知识。 高效利用给定阅读材料的方法 根据博主的实战经验来看,阅…...

C++系列-多态

🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 多态 多态就是不同类型的对象,去做同一个行为,但是产生的结果是不同的。 比如说: 都是动物叫声,猫是喵喵,狗是汪汪&am…...

基于C++和Python的进程线程CPU使用率监控工具

文章目录 0. 概述1. 数据可视化示例2. 设计思路2.1 系统架构2.2 设计优势 3. 流程图3.1 C录制程序3.2 Python解析脚本 4. 数据结构说明4.1 CpuUsageData 结构体 5. C录制代码解析5.1 主要模块5.2 关键函数5.2.1 CpuUsageMonitor::Run()5.2.2 CpuUsageMonitor::ComputeCpuUsage(…...

fish-speech语音大模型本地部署

文章目录 fish-speech模型下载编译部署 小结 fish-speech模型 先说下fish-speech模型吧,可以先看下官网。如下: 这就是一个模型,可以根据一个样例声音,构建出自己需要的声音。其实,这个还是有很多用途的;…...

如何写出更牛的验证激励

前言 芯片验证是为了发现芯片中的错误而执行的过程,它是一个破坏性的过程。完备的验证激励可以更有效地发现芯片错误,进而缩短验证周期。合格的验证激励必须能产生所有可能的验证场景(完备性),包括合法和非法的场景,并保持最大的…...

EasyCVR视频汇聚平台:解锁视频监控核心功能,打造高效安全监管体系

随着科技的飞速发展,视频监控技术已成为现代社会安全、企业管理、智慧城市构建等领域不可或缺的一部分。EasyCVR视频汇聚平台作为一款高性能的视频综合管理平台,凭借其强大的视频处理、汇聚与融合能力,在构建智慧安防/视频监控系统中展现出了…...

面对大文件(300G以上)如何加速上传速度

解题思路 采用分片上传,同时每个分片多线程上传可以加速上传速度,上传速度提升10倍左右 在阿里云OSS Go SDK中,bucket.UploadStream 函数并没有直接提供,而是通过 bucket.UploadFile 或者 bucket.PutObject 等函数来实现文件上传…...

基于 Redis 实现消息队列的深入解析

目录 Redis 消息队列简介Redis 消息队列的实现方式 2.1 使用 List 实现简单队列2.2 使用 Pub/Sub 模式实现消息发布与订阅2.3 使用 Stream 实现高级队列 Redis 消息队列的特点与优势Redis 消息队列的应用场景Redis 消息队列的局限性及应对方案总结 Redis 消息队列简介 Redis…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...