Javascript高级—深浅拷贝

浅拷贝

浅拷贝是拷贝第一层的拷贝

使用Object.assign解决这个问题。

let a = {age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1

通过展开运算符 ... 来实现浅拷贝

let a = {age: 1
}
let b = {...a};
a.age = 2;
console.log(b.age)  // 1

深拷贝

简单的做法:JSON.parse(JSON.stringfy(obj))
但是该方法也是有局限性的:

  • 会忽略undefined
  • 会忽略symbol
  • 会忽略函数
  • 不能解决循环引用的对象 (会抱错)

如果你所需拷贝的对象含有内置类型并且不包含函数,可以使用 MessageChannel

自封装深拷贝
思路:

  1. 使用for-in遍历对象
  2. 因为for-in会遍历原型链上的属性,所以需要判断属性是否在原型链上,不是原型链才拷贝
  3. 判断属性值类型是原始类型和引用类型
  4. 原始类型直接赋值(注意null)
  5. 引用类型判断是对象还是数组,创建对应的空对象或空数组,递归调用函数,将值赋值进去
/*** 深度克隆* @param   origin 被拷贝的原对象* @param   target 拷贝出来的对象* @return         拷贝出来的对象*/
function deepClone(origin, target) {target = target || {};for(let prop in origin) {   //使用 for-inif(origin.hasOwnProperty(prop)) { //是原型链上的if(typeof(origin[prop]) === 'object' && origin[prop] ) { //是对象// 先判断是不是数组if(origin[prop] instanceof Array) {target[prop] = [];deepClone(origin[prop], target[prop]);}target[prop] = {};deepClone(origin[prop], target[prop]);} else {target[prop] = origin[prop];}}}return target;
}//使用递归的方式实现数组、对象的深拷贝
function deepClone1(obj) {//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝var objClone = Array.isArray(obj) ? [] : {};//进行深拷贝的不能为空,并且是对象或者是if (obj && typeof obj === "object") {for (key in obj) {if (obj.hasOwnProperty(key)) {if (obj[key] && typeof obj[key] === "object") {objClone[key] = deepClone1(obj[key]);} else {objClone[key] = obj[key];}}}}return objClone;
}

jQuery的extend方法实现

// 实现jQuery的extend函数// v1:
function extend() {let i = 1;let len = arguments.length;let target = arguments[0];let options, copy;// 遍历第一个以后的所有参数for (; i < len; i++) {options = arguments[i];if (options != null) {for (let name in options) {copy = options[name];if (copy !== undefined) {target[name] = copy;}}}}return target;
}// TODO: 当前的这个版本不能深拷贝,只能覆盖(如果是对象属性的话)
// v2: 实现一个深度拷贝
function extend(){// 1. 默认是不进行深拷贝的let deep = false;let len = arguments.length;let i = 1;// 第一个参数如果不是一个bool的话,target默认就是第一个参数let target = arguments[0] || {};let options, src, copy;if (typeof target === 'boolean') {deep = target;target = arguments[i] || {};i++;}// 如果target不是对象的话,无法复制,设置为{}if (typeof target !== 'object') {target = {};}// 开始深拷贝for (; i < len; i++) {options = arguments[i];if (options != null) {for (let name in options) {// 开始准备源数据和目标数据src = target[name];copy = options[name];// 如果是对象的话,就深拷贝if (deep && copy && typeof copy === 'object') {target[name] = extend(deep, src, copy);}else if (copy !== undefined) {// 普通数据类型的话target[name] = copy;}}}}return target;
}// isPlainObject 函数来自于  [JavaScript专题之类型判断(下) ](https://github.com/mqyqingfeng/Blog/issues/30)
var class2type = {};
var toString = class2type.toString;
var hasOwn = class2type.hasOwnProperty;function isPlainObject(obj) {var proto, Ctor;if (!obj || toString.call(obj) !== "[object Object]") {return false;}proto = Object.getPrototypeOf(obj);if (!proto) {return true;}Ctor = hasOwn.call(proto, "constructor") && proto.constructor;return typeof Ctor === "function" && hasOwn.toString.call(Ctor) === hasOwn.toString.call(Object);
}function extend() {// 默认不进行深拷贝var deep = false;var name, options, src, copy, clone, copyIsArray;var length = arguments.length;// 记录要复制的对象的下标var i = 1;// 第一个参数不传布尔值的情况下,target 默认是第一个参数var target = arguments[0] || {};// 如果第一个参数是布尔值,第二个参数是 targetif (typeof target == 'boolean') {deep = target;target = arguments[i] || {};i++;}// 如果target不是对象,我们是无法进行复制的,所以设为 {}if (typeof target !== "object" && !isFunction(target)) {target = {};}// 循环遍历要复制的对象们for (; i < length; i++) {// 获取当前对象options = arguments[i];// 要求不能为空 避免 extend(a,,b) 这种情况if (options != null) {for (name in options) {// 目标属性值src = target[name];// 要复制的对象的属性值copy = options[name];// 解决循环引用if (target === copy) {continue;}// 要递归的对象必须是 plainObject 或者数组if (deep && copy && (isPlainObject(copy) ||(copyIsArray = Array.isArray(copy)))) {// 要复制的对象属性值类型需要与目标属性值相同if (copyIsArray) {copyIsArray = false;clone = src && Array.isArray(src) ? src : [];} else {clone = src && isPlainObject(src) ? src : {};}target[name] = extend(deep, clone, copy);} else if (copy !== undefined) {target[name] = copy;}}}}return target;
};let obj1 = {a: 1,b: { b1: 1, b2: 2 }
};let obj2 = {b: { b1: 3, b3: 4 , b4: 5},c: 3
};let obj3 = {d: 4
}
console.log(extend(obj1, obj2, obj3));<<<<<<< HEAD
console.log('---------------------');var a = extend(true, [4, 5, 6, 7, 8, 9], [1, 2, 3]);
console.log(a) // ???console.log('---------------------');
var obj11 = {value: {3: 1}
}var obj22 = {value: [5, 6, 7],}var b = extend(true, obj11, obj22) // ???
var c = extend(true, obj22, obj11) // ???
console.log(b, c)// 补充:深度克隆
function deepClone(obj) {let res = Array.isArray(obj) ? [] : {};for (let key in obj) {if (obj.hasOwnProperty(key)) {if (obj[key] && typeof obj[key] === 'object') {res[key] = deepClone(obj[key]);}else {res[key] = obj[key];}}}return res;
}

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

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

相关文章

【Matlab算法】MATLAB实现基于小波变换的信号去噪(附MATLAB完整代码)

MATLAB实现基于小波变换的信号去噪 结果图前言正文1. 小波变换理论基础1.1 小波变换的数学模型1.2 离散小波变换原理2. 信号去噪方法2.1 去噪算法流程2.2 阈值处理方法3. 核心函数解析3.1 wavedec函数3.2 wthresh函数代码实现4.1 信号生成4.2 小波变换去噪完整代码总结参考文献…

神经网络基础--什么是正向传播??什么是方向传播??

前言 本专栏更新神经网络的一些基础知识&#xff1b;这个是本人初学神经网络做的笔记&#xff0c;仅仅堆正向传播、方向传播进行了讲解&#xff0c;更加系统的讲解&#xff0c;本人后面会更新《李沐动手学习深度学习》&#xff0c;会更有详细讲解;案例代码基于pytorch&#xf…

函数式编程Stream流(通俗易懂!!!)

目录 1.Lambda表达式 1.1 基本用法 1.2 省略规则 2.Stream流 2.1 常规操作 2.1.1 创建流 2.1.2 中间操作 filter map distinct sorted limit ​编辑skip flatMap 2.1.3 终结操作 foreach count max&min collect anyMatch allMatch noneMatch …

AMD-OLMo:在 AMD Instinct MI250 GPU 上训练的新一代大型语言模型。

AMD-OLMo是一系列10亿参数语言模型&#xff0c;由AMD公司在AMD Instinct MI250 GPU上进行训练&#xff0c;AMD Instinct MI250 GPU是一个功能强大的图形处理器集群&#xff0c;它利用了OLMo这一公司开发的尖端语言模型。AMD 创建 OLMo 是为了突出其 Instinct GPU 在运行 “具有…

使用服务器时进行深度学习训练时,本地必须一直保持连接状态吗?

可以直接查看方法&#xff0c;不看背景 1.使用背景2. 方法2.1 screen命令介绍2.2 为什么要使用screen命令2.3 安装screen2.4 创建session2.5 查看session是否创建成功2.6 跳转进入session2.7 退出跑代码的session2.8 删除session 1.使用背景 我们在进行深度学习训练的时候&…

深入了解区块链:Web3的基础架构与发展

在数字时代的浪潮中&#xff0c;区块链技术正逐渐成为Web3的重要基础&#xff0c;重新定义互联网的结构和用户体验。Web3不仅是一个全新的网络阶段&#xff0c;更代表了一种去中心化的理念&#xff0c;强调用户主权和数据隐私。本文将深入探讨区块链在Web3中的基础架构、技术特…

华为大变革?仓颉编程语言会代替ArkTS吗?

在华为鸿蒙生态系统中&#xff0c;编程语言的选择一直是开发者关注的焦点。近期&#xff0c;华为推出了自研的通用编程语言——仓颉编程语言&#xff0c;这引发了关于仓颉是否会取代ArkTS的讨论。本文将从多个角度分析这两种语言的特点、应用场景及未来趋势&#xff0c;探讨仓颉…

【C++笔记】C++三大特性之继承

【C笔记】C三大特性之继承 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】C三大特性之继承前言一.继承的概念及定义1.1 继承的概念1.2继承的定义1.3继承基类成员访问方式的变化1.4继承类模板 二.基类和派生类间的转…

Windows搭建流媒体服务并使用ffmpeg推流播放rtsp和rtmp流

文章目录 搭建流媒体服务方式一安装mediamtx启动meidamtx关闭meidamtx 方式二安装ZLMediaKit启动ZLMediaKit关闭ZLMediaKit 安装FFmpeg进行推流使用FFmpeg进行rtmp推流使用VLC播放rtmp流停止FFmpeg的rtmp推流使用FFmpeg进行rtsp推流使用VLC播放rtmp流停止FFmpeg的rtsp推流 本文…

Polybase要求安装orcale jre 7

在安装SQL SERVER时&#xff0c;遇到以下情况&#xff1a;polybase要求安装orcale jre 7更新 51或更高版本 不想安装JDK7。可通过不安装polybase的功能来实现下一步的安装。 1. 点击上一步&#xff0c;回到功能选择的设置界面中。 2. 然后在功能选择窗口中&#xff0c;取消勾选…

深入理解计算机系统 3.7 缓冲区溢出

3.7.1 数据对齐 许多计算机系统对基本数据类型的合法地址做出了一些限制&#xff0c;要求某种类型对象的地址必须是某个值K(通常是2、4或8)的倍数。这种对齐限制简化了形成处理器和内存系统之间接口的硬件设计。例如&#xff0c;假设一个处理器总是从内存中取8个字节&#xff…

代码随想录刷题记录(二十七)——55. 右旋字符串

&#xff08;一&#xff09;问题描述 55. 右旋字符串&#xff08;第八期模拟笔试&#xff09;https://kamacoder.com/problempage.php?pid1065字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k&#xff0c;请编写一个函数&…

QT打包应用程序文件步骤

QT应用程序&#xff08;.exe&#xff09;打包复制到其他电脑 在QT程序在自己电脑编译好了后&#xff0c;需要打包给其他人。这里介绍一下详细步骤&#xff1a; 确定编译器 搜了很多相关的打包教程&#xff0c;但是还是会出现“应用程序无法正常启动(0xc000007b)”这类错误。经过…

我谈维纳(Wiener)复原滤波器

Rafael Gonzalez的《数字图像处理》中&#xff0c;图像复原这章内容几乎全错。上篇谈了图像去噪&#xff0c;这篇谈图像复原。 图像复原也称为盲解卷积&#xff0c;不处理点扩散函数&#xff08;光学传递函数&#xff09;的都不是图像复原。几何校正不属于图像复原&#xff0c…

10款音频剪辑推荐!!你的剪辑好帮手!!

在如今的数据化浪潮中&#xff0c;工作已经采用了线上线下相结合。我的工作就需要借助一些剪辑工具&#xff0c;来实现我对音频工具的剪辑。我初次接触到音频剪辑也是因为工作需求&#xff0c;从起初我只是一个音频剪辑的小白&#xff0c;这些工具的协助。吸引着我。对于这些工…

Rocky、Almalinux、CentOS、Ubuntu和Debian系统初始化脚本v9版

Rocky、Almalinux、CentOS、Ubuntu和Debian系统初始化脚本 Shell脚本源码地址&#xff1a; Gitee&#xff1a;https://gitee.com/raymond9/shell Github&#xff1a;https://github.com/raymond999999/shell脚本可以去上面的Gitee或Github代码仓库拉取。 支持的功能和系统&am…

Scrapy搭配Selenium爬取豆瓣电影250排行榜动态网页数据

参考CSDN博客&#xff1a;https://blog.csdn.net/qq_43213783/article/details/113063557 2024年11月11日实现。 创建movie_douban爬虫项目&#xff1a; scrapy startproject movie_douban 进入spiders&#xff1a; cd movie_douban/movie_douban/spiders 创建doubanMovieSpi…

想定制RK3566/3568安卓11开机logo吗?触觉智能Purple Pi OH来教你

本文介绍瑞芯微RK3566/RK3568主板/开发板安卓Android11系统替换开机Logo的方法&#xff0c;使用触觉智能Purple Pi OH鸿蒙开发板演示&#xff0c;搭载了瑞芯微RK3566芯片&#xff0c;4核1.8Ghz1T算力NPU&#xff1b;类树莓派设计&#xff0c;Laval社区主荐&#xff0c;已适配全…

【AliCloud】ack + ack-secret-manager + kms 敏感数据安全存储

介绍 ack-secret-manager支持以Kubernetes Secret实例的形式向集群导入或同步KMS凭据信息&#xff0c;确保您集群内的应用能够安全地访问敏感信息。通过该组件&#xff0c;您可以实现密钥数据的自动更新&#xff0c;使应用负载通过文件系统挂载指定Secret实例来使用凭据信息&a…

网页设计平台:6个技术亮点

想要创建个人或商业网站来分享知识或推广商品吗&#xff1f;这篇文章将为你介绍6个免费的网页制作平台&#xff0c;帮助你即使没有编程基础也能快速、轻松地搭建出专业且引人注目的网站。让我们一起探索这些平台&#xff0c;发现它们的特色和优势。 即时设计 即时设计是一个云…