详解JS深拷贝与浅拷贝

详解JS深拷贝与浅拷贝

一、什么是拷贝

在JavaScript中,我们经常需要对一个数据进行拷贝,这里的拷贝指的是将一个数据重新复制一份,从而在新的数据上进行操作,而原始数据不会受到影响。拷贝手段分为两种:浅拷贝和深拷贝。

1.1 浅拷贝

浅拷贝就是将原始数据的引用复制一份给新的数据,这样新数据和原始数据指向同一块内存区域,因此对新数据进行操作,也会影响原始数据。

示例代码:

let obj = {a: 1, b: {c: 2}};
let newObj = obj;
newObj.a = 3;
newObj.b.c = 4;
console.log(obj); // {a: 3, b: {c: 4}}

可以看到,对 newObj 进行操作,同时也影响了 obj

1.2 深拷贝

深拷贝是将原始数据完整地复制一份给新的数据,新数据和原始数据没有任何联系,对新数据的操作也不会影响原始数据。

示例代码:

let obj = {a: 1, b: {c: 2}};
let newObj = JSON.parse(JSON.stringify(obj));
newObj.a = 3;
newObj.b.c = 4;
console.log(obj); // {a: 1, b: {c: 2}}
console.log(newObj); // {a: 3, b: {c: 4}}

可以看到,对 newObj 进行操作,并不影响 obj

二、浅拷贝的实现方法

2.1 Object.assign()

Object.assign()方法将所有的可枚举属性的值从一个或多个源对象复制到目标对象。它会先创建一个新对象,然后将源对象的属性拷贝到新对象上。

示例代码:

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

可以看到,对 obj2 进行操作,并不影响 obj1

2.2 扩展运算符 ...

扩展运算符 ... 也可以实现浅拷贝。它能够将一个数组或对象展开成一系列参数,方便地将其插入一个函数或对象字面量中。

示例代码:

let obj1 = {a: 1,b: {c: 2}};
let obj2 = {...obj1};
obj2.a = 3;
obj2.b.c = 4;
console.log(obj1); // {a: 1, b: {c: 4}}
console.log(obj2); // {a: 3, b: {c: 4}}

可以看到,对 obj2 进行操作,并不影响 obj1

三、深拷贝的实现方法

3.1 手写递归函数

手写递归函数可以非常方便地实现深拷贝,它会遍历对象的所有属性和子属性,并将其转化为一个新的对象返回。

示例代码:

function deepClone(obj) {
  let newObj = Array.isArray(obj) ? [] : {};
  if (obj && typeof obj === "object") {
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        newObj[key] = deepClone(obj[key]);
      }
    }
  }
  else {
    newObj = obj;
  }
  return newObj;
}

let obj1 = {a: 1,b: {c: 2}};
let obj2 = deepClone(obj1);
obj2.a = 3;
obj2.b.c = 4;
console.log(obj1); // {a: 1, b: {c: 2}}
console.log(obj2); // {a: 3, b: {c: 4}}

可以看到,对 obj2 进行操作,并不影响 obj1

3.2 使用第三方包

第三方包 lodash 中的 _.cloneDeep() 方法也可以实现深拷贝。这个方法可以递归地复制一个 JavaScript 对象。

示例代码:

const _ = require('lodash');

let obj1 = {a: 1,b: {c: 2}};
let obj2 = _.cloneDeep(obj1);
obj2.a = 3;
obj2.b.c = 4;
console.log(obj1); // {a: 1, b: {c: 2}}
console.log(obj2); // {a: 3, b: {c: 4}}

可以看到,对 obj2 进行操作,并不影响 obj1

四、深度递归拷贝的注意事项

在深度递归拷贝中,需要注意以下几点:

  1. 对 Date、RegExp、Function 等对象无法进行深拷贝,需要特殊处理。
  2. 对于对象的循环引用,需要避免死循环。

五、总结

浅拷贝只是复制了一个对象的引用,而深拷贝则是复制了整个对象。使用递归函数实现深拷贝时,需要考虑到各种对象类型的情况。如果对数据的操作需要保证原始数据的不变性,建议使用深拷贝。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解JS深拷贝与浅拷贝 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • javascript页面上使用动态时间具体实现

    我们来详细讲解一下Javascript页面上使用动态时间的具体实现。 一、实现方法 1.使用setInterval()方法实现动态时间 Javascript可以通过setInterval()方法,每隔一定时间执行一段代码,源码如下: setInterval(function(){ // 在此处执行需要执行的代码 }, 时间间隔); 其中,第一个参数是需要每隔…

    JavaScript 2023年5月27日
    00
  • 一些常用的JavaScript函数(json)附详细说明

    下面是关于“一些常用的JavaScript函数(json)附详细说明”的整个攻略: 一些常用的JavaScript函数(json)附详细说明 1. JSON.parse() JSON.parse() 方法可以将符合 JSON 格式的字符串转换为对应的 JavaScript 对象或数组。该方法常用于在客户端接收后台返回的 JSON 格式数据并在前端进行解析和处…

    JavaScript 2023年6月11日
    00
  • JS变量中有var定义和无var定义的区别以及es6中let命令和const命令

    JS变量中有var定义和无var定义的区别 在Javascript中,有使用var定义变量和不使用var直接定义变量两种方式。 1. 使用var定义变量 使用var定义的变量会存在变量提升,即在变量声明之前,该变量也可以被访问到。这种定义方式的变量作用域是该变量所在的函数作用域(如果在函数内定义)或全局作用域(如果在函数外定义)。 示例1:使用var定义变量…

    JavaScript 2023年6月10日
    00
  • JS获取并处理php数组的方法实例分析

    作为网站的作者,我来为大家详细讲解一下 “JS获取并处理php数组的方法实例分析” 的攻略。 1. 什么是PHP数组? 在PHP中,数组(array)是一种保存一个或多个值的数据结构。它可以在一个单独的变量中存储多个值,并且这些值可以是不同的类型。 PHP数组是一个关联数组,它可以使用数字或字符串作为键来访问元素。 下面是一个简单的PHP数组示例,其中元素使…

    JavaScript 2023年5月19日
    00
  • Android中Okhttp3实现上传多张图片同时传递参数

    完整攻略: 导入Okhttp3库 首先需要在项目中导入Okhttp3库。在build.gradle文件中添加以下依赖: implementation ‘com.squareup.okhttp3:okhttp:4.9.1’ 实现上传多张图片 使用Okhttp3上传多张图片可以借助MultipartBody方式,具体实现过程如下: //创建OkHttpClien…

    JavaScript 2023年6月10日
    00
  • JavaScript中对象property的读取和写入方法介绍

    下面我就来为你详细讲解“JavaScript中对象property的读取和写入方法介绍”。 什么是对象property 在JavaScript中,对象是一种基本类型,它由key-value键值对组成。对象的属性可以是任意的JavaScript值,例如数字、布尔值、字符串、函数、甚至可以是另一个对象。在JavaScript中,我们使用点(.)或方括号([])访…

    JavaScript 2023年5月27日
    00
  • 原生JS实现动态加载js文件并在加载成功后执行回调函数的方法

    实现动态加载 js 文件是网页开发中常见的需求,可以用于按需加载某些功能模块,减轻网页初始加载时的压力。同时,当加载完成时,需要执行相应的回调函数,以便进行后续的操作。下面是实现原生 JavaScript 实现动态加载 js 文件并执行回调函数的完整攻略: 1. 原生JS实现动态加载js文件 我们可以通过创建一个 script 标签来实现动态加载 js 文件…

    JavaScript 2023年5月27日
    00
  • 彻底解决页面文字编码乱码问题

    彻底解决页面文字编码乱码问题的攻略主要分为以下几个步骤: 1. 确认网页编码 在解决页面文字编码乱码问题之前,我们需要先确定当前网页的编码方式。常见的网页编码方式有 UTF-8、GB2312、GBK 等等。你可以通过查看网页源代码的 meta 标签或者请求头中的 content-type 信息来确认编码方式。 一般情况下,我们推荐网页使用 UTF-8 编码,…

    JavaScript 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部