【JavaScript】面试手撕浅拷贝

news2024/9/22 8:18:49

【JavaScript】面试手撕浅拷贝

引入

浅拷贝和深拷贝应该是面试时非常常见的问题了,为了能将这两者说清楚,于是打算用两篇文章分别解释下深浅拷贝。

PS: 我第一次听到拷贝这个词,有种莫名的熟悉感,感觉跟某个英文很相似,后来发现确实Copy的音译,感觉这翻译还是蛮有意思的。🐶

什么是浅拷贝

行文至此,肯定会有朋友问,什么事浅拷贝呢?顾名思义,就是浅浅的copy一下。🐶

JavaScript中,对于浅拷贝分为两种情况。

  • 对于浅拷贝,如果待拷贝的数据是基础类型的属性(如NumberStringBoolean等基本类型),那么只需要将这个值直接复制过来即可
  • 对于浅拷贝,如果待拷贝的数据是引用类型的属性(如对象,数组),那么复制的则是对象的引用以及第一层的基础属性值

基础类型与引用类型的区别

谈到这,顺带谈一下基础类型引用类型的区别。

基础类型
  • 直接存储在栈内存中。
  • 存储的是实际的数据值。
  • 内存空间固定且较小。
引用类型
  • 对象(如数组,函数,对象等)的属性值存在堆内存中。
  • 栈内存中存储的是指向堆内存中对象的引用或指针,而非对象本身的内容。
  • 内存空间大小不固定,取决于对象结构的复杂性。

手动实现浅拷贝

因为值的拷贝可以直接赋值即可。我们这里实现下对象的浅拷贝。

对象的浅拷贝:复制对象的引用以及第一层属性值。

思路: 我们先构造一个新对象,然后将它的属性值等于原对象的属性值。这里新对象和原对象的属性依然会共享引用,但对于第一层的基础属性却不会共享了。所以我们实现的浅拷贝 是拷贝一层。

function shallowClone(obj) {
  const newObj = {};
  for (let prop in obj) {
    if (obj.hasOwnProperty(prop)) {
      newObj[prop] = obj[prop];
    }
  }
  return newObj;
}

const test = { a: 1, b: 2 };
const newTest = shallowClone(test);
newTest.a = 2;
console.log('test: ',test,' newTest: ', newTest);
/**
 * 输入如下,第一层基础属性的值不会共享了
 * test:  { a: 1, b: 2 }  newTest:  { a: 2, b: 2 }
 */

Js自带浅拷贝的方法

对于Js的浅拷贝,可以分为对象浅拷贝数组浅拷贝

对象浅拷贝

对于对象的浅拷贝有object.assgin拓展运算符实现,这里的浅拷贝都是拷贝一层。

Object.assign

Object.assign()ES6 中引入的一个方法,用于将一个或多个源对象的所有可枚举属性分配到目标对象上。

const original = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, original);
拓展运算符

注意:这种方式同样会创建一个新的对象,但对嵌套对象或数组只会进行浅拷贝。

const original = { a: 1, b: { c: 2 } };
const shallowCopy = { ...original };

数组浅拷贝

slice

slice()方法是用来从数组中提取一部分元素生成新数组的方法,它确实实现了数组的浅拷贝。

let originalArray = [1, 2, { a: 3 }, [4, 5]];
let copiedArray = originalArray.slice();

// 浅拷贝后,原始数组和拷贝数组中基本类型元素是独立的
copiedArray[0] = 100; // 修改基本类型元素,不影响原数组
console.log(originalArray); // 输出:[1, 2, { a: 3 }, [4, 5]]
console.log(copiedArray); // 输出:[100, 2, { a: 3 }, [4, 5]]

// 但是对于引用类型元素,修改其属性或内容会同时影响原数组和拷贝数组
copiedArray[2].a = 456;
copiedArray[3][0] = 7;

console.log(originalArray); // 输出:[1, 2, { a: 456 }, [7, 5]]
console.log(copiedArray); // 输出:[100, 2, { a: 456 }, [7, 5]]

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

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

相关文章

2024全国护网行动HW行动招聘/收人!!!

2024全国护网行动HW行动招聘 溯蓉信创开始收人啦!!!现在开始收录2024HW简历,感兴趣的小伙伴扫码二维码添加微信 我们签约后,入场即预付款3k,签约后我们会在HW之前对我们的人员进行HW培训,保证上…

光辐射测量(1)基本介绍+辐射度量、光辐射度量基础

基本情况:本门课就是对“三度学”进行学习。“三度学”包括辐射度学、光度学、色度学。主要掌握其基本概念、原理、物理量的互相转换关系、计算分析方法、测量仪器与测试计量方法等。 三者所覆盖的范围如图。 辐射度学: 辐射度学是一门研究电磁辐射能测…

TikTok矩阵获客软件开发需要了解的代码!

在数字营销领域,TikTok已经成为一个不可忽视的平台,由于其庞大的用户群体和高度互动性,越来越多的企业开始寻求在TikTok上进行有效的获客策略。 为了实现这一目标,开发一款针对TikTok的矩阵获客软件成为了许多企业的选择&#xf…

力扣刷题:206.反转链表

题目: 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1]示例 2: 输入:head [1,2] 输出:[2,1]示例 3&am…

day11_oop_fianl_satic_多态

今日内容 零、 复习昨日 一、final 二、static 三、多态 四、向上转型&向下转型 五、多态应用 零、 复习昨日 0 类封装步骤 属性私有private提供setget方法 1 继承关键词,继承的好处 extends减少代码重复为多态做准备 2 子类可以使用父类什么 非私有的属性和方法 3 方法重写…

java数据结构与算法刷题-----LeetCode337. 打家劫舍 III

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 动态规划深度优先1.1 解题思路和细节2.2 代码实现 很多人觉得…

vue项目中使用antvX6新手教程,附demo案例讲解(可拖拽流程图、网络拓扑图)

前言: 之前分别做了vue2和vue3项目里的网络拓扑图功能,发现对antv X6的讲解博客比较少,最近终于得闲码一篇了! 需求: 用户可以自己拖拽节点,节点之间可以随意连线,保存拓扑图数据后传给后端&…

恒峰|智能高压森林应急消防泵|森林防火的守护神

在大自然中,森林是生态系统的重要组成部分,它们为我们提供氧气、净化空气、保持水源、防止土壤侵蚀等重要功能。然而,森林火灾却时常威胁着这些宝贵资源的安全。为了应对这一挑战,我们研制出了一种名为“智能高压森林应急消防泵”…

游戏寻路之A*算法(GUI演示)

一、A*算法介绍 A*算法是一种路径搜索算法,用于在图形网络中找到最短路径。它结合了Dijkstra算法和启发式搜索的思想,通过综合利用已知的最短路径和估计的最短路径来优化搜索过程。在游戏自动寻路得到广泛应用。 二、A*算法的基本思想 在图形网络中选择一个起点和终点。维护…

OSPF 普通区域stub实验简述

1、OSPF 普通区域stub配置 实验拓扑图 r1: sys sysname r1 undo info enable int loopb 0 ip add 1.1.1.1 32 quit int e0/0/0 ip add 172.16.1.1 24 quit ospf 1 area 0.0.0.1 network 172.16.1.0 0.0.0.255 network 1.1.1.1 0.0.0.0 Stub 配置普通区域 ret r6: sys sysnam…

不愧是华为出来的,太厉害了...

🍅 视频学习:文末有免费的配套视频可观看 🍅 关注公众号【互联网杂货铺】,回复 1 ,免费获取软件测试全套资料,资料在手,涨薪更快 实习去了博彦科技(外包),做的…

认识AJAX

一、什么是Ajax? 有跳转就是同步,无跳转就是异步 Asynchronous Javascript And XML(异步JavaScript和XML) Ajax 异步 JavaScript 和XML。Ajax是一种用于创建快速动态网页的技术通过在后台与服务器进行少量数据交换,Ajax可以使网…

SpringMVC01、回顾MVC

1、回顾MVC 1.1、什么是MVC MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。是将业务逻辑、数据、显示分离的方法来组织代码。MVC主要作用是降低了视图与业务逻辑间的双向偶合。MVC不是一种设计模式,MVC是一种架构模式。…

基本运算符

参考C Primer Plus进行C语言学习 文章目录 基本运算符 除法运算符:/其他运算 1、除法运算符 在C语言中,整数除法结果的小数部分被丢弃,这一过程被称为截断。 2.其他运算符 (1)sizeof运算符和size_t类型 回顾一下&…

代码随想录算法训练营三刷day13 |栈与队列 之 239. 滑动窗口最大值 347.前 K 个高频元素

三刷day13 239. 滑动窗口最大值347.前 K 个高频元素 239. 滑动窗口最大值 题目链接 解题思路: 设计单调队列的时候,pop和push操作要保持如下规则: pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队…

Jumpserver堡垒机搭建

Jumpserver概述: Jumpserver优势:

DevOps学习 | 如何应对IT服务交付中的问题?

目录 前言 DevOps是什么? DevOps发展历程 DevOps与微服务、容器的关系 书本推荐 前言 作为一个热门的概念,DevOps这个名词在程序员社区里频频出现,备受技术大佬们的追捧。甚至网络上有了“南无DevOps”的戏言(南无在梵语的意…

(学习日记)2024.03.04:UCOSIII第六节:main函数+前六节总结

写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…

连锁线上线下门店管理为什么需要使用分账系统

连锁线上线下门店管理的复杂性要求采用有效的分账系统,以实现降低税务风险、保障资金安全和合规运营。首先,通过分账系统,可以清晰记录不同门店的收入和支出情况,有利于确保税务合规性。其次,分账系统有助于将不同门店…

Scratch 第十六课-弹珠台游戏

第十六课-弹珠台游戏 大家好,今天我们一起做一款弹珠台scratch游戏,我们也可以叫它弹球游戏!这款游戏在刚出来的时候非常火爆。小朋友们要认真学习下! 这节课的学习目标 物体碰撞如何处理转向问题。复习键盘对角色的控制方式。…