js深拷贝

简介: 了解并掌握js深拷贝

js深拷贝

在讲正题之前我们要先了解数据存储的方式

数据存储方式

在讲之前我们要先知道值类型和引用类型的存储方式。

在JavaScript数据类型中有两种数据类型。

值类型字符串(String)、数字 (Number)、布尔 (Boolean)、空(Null)、未定义(Undefined)、Symbol

。存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。

引用数据类型对象 (Object)数组 (Array)函数 (Function)

存放在堆内存中的对象,在栈内存中存的是一个指针,这个指针指向堆内存一个位置。再从堆内存中取得所需的数据。

存储如下图:

在这里插入图片描述

什么是浅/深拷贝

讲完存储的方式,我们来讲讲浅拷贝和深拷贝

拷贝也就是我们常常讲的copy,ctrl+c,ctrl+v,那么我们来看看例子

当我们对分别值类型和引用类型进行赋值。

     var a = 5
     var b = a
     b += 5
     console.log('a=' + a,'b=' + b)
     var arr=[1,2,3]
     var brr=arr
     brr.push(10)
     console.log("arr为",arr)
     console.log("brr为",brr)

在这里插入图片描述

现象:我们发现值类型并没有互相受到影响,然而数组(引用类型)brr数组添加元素的时候改变了arr数组。

解释分析:浅拷贝只会发生在引用类型身上,对于引用类型如果之进行简单的赋值,只会赋值指向堆内存的指针,这种称为浅拷贝。而深拷贝就是完全拷贝一个引用类型,为不是地址指针。

浅拷贝看下面这张原理图:

在这里插入图片描述

常用深拷贝实现

那么我们在赋值引用类型的时候肯定不能出现浅拷贝的现象,对原数据产生影响了。那么就要进行深拷贝

1.通过JSON.stringify和JSON.parse

可以深拷贝的数组和对象,但是不能拷贝函数,可以进行对象或者数组的嵌套拷贝。

缺点:无法实现对对象中方法的深拷贝

使用:

     var brr=JSON.parse(JSON.stringify(arr))

例子:

  var arr = {
         name: '浪漫主义码农',
         age: 20,
         adress: ['jiangxi', 'changsha'],
         friends: {
             friend1: '张三',
             friend2: '李四'
         },
         function(){
             console.log("我是浪漫主义的对象")
         }
     }
     var brr=JSON.parse(JSON.stringify(arr))
     brr.name='法外狂徒张三'
     brr.adress[0]='长沙'
     console.log("arr为", arr)
     console.log("brr为", brr)

在这里插入图片描述

2.扩展运算符

利用了对象的结构赋值特性方法。

缺点:无对对象里面嵌套的对象进行深拷贝,相当于只是对一层引用对象进行深拷贝

使用:

     var brr={...arr}

例子:

  var arr = {
         name: '浪漫主义码农',
         age: 20,
         adress: ['jiangxi', 'changsha'],
         friends: {
             friend1: '张三',
             friend2: '李四'
         },
         function(){
             console.log("我是浪漫主义的对象")
         }
     }
     var brr={...arr}
     brr.name='法外狂徒张三'
     brr.adress[0]='长沙'
     console.log("arr为", arr)
     console.log("brr为", brr)

在这里插入图片描述

3.手写递归深拷贝函数

完美解决

函数:

  //使用递归实现深拷贝
     function deepClone(obj) {
         //判断拷贝的obj是对象还是数组
         var objClone = Array.isArray(obj) ? [] : {};
         if (obj && typeof obj === "object") { //obj不能为空,并且是对象或者是数组 因为null也是object
             for (key in obj) {
                 if (obj.hasOwnProperty(key)) {
                     if (obj[key] && typeof obj[key] === "object") { //obj里面属性值不为空并且还是对象,进行深度拷贝
                         objClone[key] = deepClone(obj[key]); //递归进行深度的拷贝
                     } else {
                         objClone[key] = obj[key]; //直接拷贝
                     }
                 }
             }
         }
         return objClone;
     }

例子:

      var arr = {
         name: '浪漫主义码农',
         age: 20,
         adress: ['jiangxi', 'changsha'],
         friends: {
             friend1: '张三',
             friend2: '李四'
         },
         fun: function(){
             console.log("我是" + this.name + "的对象")
         }
     }
     var brr = deepClone(arr)
     brr.name = '法外狂徒张三'
     brr.adress[0] = '长沙'
     console.log("arr为", arr)
     arr.fun()
     console.log("brr为", brr)
     brr.fun()
 ​
     //使用递归实现深拷贝
     function deepClone(obj) {
         //判断拷贝的obj是对象还是数组
         var objClone = Array.isArray(obj) ? [] : {};
         if (obj && typeof obj === "object") { //obj不能为空,并且是对象或者是数组 因为null也是object
             for (key in obj) {
                 if (obj.hasOwnProperty(key)) {
                     if (obj[key] && typeof obj[key] === "object") { //obj里面属性值不为空并且还是对象,进行深度拷贝
                         objClone[key] = deepClone(obj[key]); //递归进行深度的拷贝
                     } else {
                         objClone[key] = obj[key]; //直接拷贝
                     }
                 }
             }
         }
         return objClone;
     }

在这里插入图片描述

写在最后

如果有误,欢迎大佬在评论区留言。

💌 “远赴人间惊鸿宴,一睹人间盛世颜” 💌

一个心怀浪漫宇宙,也珍惜人间日常的码农
在这里插入图片描述
**

相关文章
|
8月前
|
JSON JavaScript 数据格式
深拷贝和浅拷贝(js的问题)
深拷贝和浅拷贝(js的问题)
37 0
|
3月前
|
JavaScript 前端开发
JavaScript中的深拷贝与浅拷贝
JavaScript中的深拷贝与浅拷贝
55 4
|
4月前
|
JSON JavaScript 数据格式
手写JS实现深拷贝函数
本文介绍了如何实现一个深拷贝函数`deepClone`,该函数可以处理对象和数组的深拷贝,确保拷贝后的对象与原始对象在内存中互不干扰。通过递归处理对象的键值对和数组的元素,实现了深度复制,同时保留了函数类型的值和基础类型的值。
28 3
|
5月前
|
JavaScript 前端开发
JavaScript中的深拷贝与浅拷贝
JavaScript中的深拷贝与浅拷贝
49 2
|
5月前
|
JavaScript 前端开发
JavaScript中的深拷贝和浅拷贝的实现讲解
在JavaScript中,浅拷贝与深拷贝用于复制对象。浅拷贝仅复制基本类型属性,对于引用类型仅复制引用,导致双方共享同一数据,一方修改会影响另一方。深拷贝则完全复制所有层级的数据,包括引用类型,确保双方独立。浅拷贝可通过简单属性赋值实现,而深拷贝需递归复制各层属性以避免共享数据。
77 1
|
7月前
|
JSON JavaScript 前端开发
【JavaScript】JavaScript中的深拷贝与浅拷贝详解:基础概念与区别
JavaScript 中,理解数据拷贝的深浅至关重要。浅拷贝(如扩展运算符`...`、`Object.assign()`)仅复制对象第一层,共享内部引用,导致修改时产生意外联动。深拷贝(如自定义递归函数、`_.cloneDeep`或`JSON.parse(JSON.stringify())`)创建独立副本,确保数据隔离。选择哪种取决于性能、数据独立性和资源需求。深拷贝虽慢,但确保安全;浅拷贝快,但需小心引用共享。在面试中,理解这些概念及其应用场景是关键。
142 4
【JavaScript】JavaScript中的深拷贝与浅拷贝详解:基础概念与区别
|
5月前
|
JavaScript 前端开发
js中浅拷贝和深拷贝的区别
js中浅拷贝和深拷贝的区别
34 0
|
5月前
|
JavaScript 前端开发
js中浅拷贝,深拷贝的实现
js中浅拷贝,深拷贝的实现
39 0
|
6月前
|
JavaScript
js【详解】深拷贝 (含 JSON.parse(JSON.stringify(obj)) 的缺陷,5种手写深拷贝)
js【详解】深拷贝 (含 JSON.parse(JSON.stringify(obj)) 的缺陷,5种手写深拷贝)
191 0
|
6月前
|
存储 JavaScript 前端开发
javascript的栈内存 VS 堆内存(浅拷贝 VS 深拷贝)
javascript的栈内存 VS 堆内存(浅拷贝 VS 深拷贝)
35 0