如何彻底掌握实现JavaScript深拷贝的多种方法?

2026-04-05 17:321阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1370个文字,预计阅读时间需要6分钟。

如何彻底掌握实现JavaScript深拷贝的多种方法?

目录 + JS深拷贝 + 数据存储方式 + 什么是浅/深拷贝 + 常用深拷贝实现 + 1. 通过JSON.stringify和JSON.parse + 2. 扩展运算符 + 3. 手写递归深拷贝函数 + 总结 + JS深拷贝 + 在讲解正题之前,我们首先要了解数据存储的方式

目录
  • js深拷贝
    • 数据存储方式
    • 什么是浅/深拷贝
    • 常用深拷贝实现
      • 1.通过JSON.stringify和JSON.parse
      • 2.扩展运算符
      • 3.手写递归深拷贝函数
  • 总结

    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)

    如何彻底掌握实现JavaScript深拷贝的多种方法?

    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; }

    总结

    本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注自由互联的更多内容!

    本文共计1370个文字,预计阅读时间需要6分钟。

    如何彻底掌握实现JavaScript深拷贝的多种方法?

    目录 + JS深拷贝 + 数据存储方式 + 什么是浅/深拷贝 + 常用深拷贝实现 + 1. 通过JSON.stringify和JSON.parse + 2. 扩展运算符 + 3. 手写递归深拷贝函数 + 总结 + JS深拷贝 + 在讲解正题之前,我们首先要了解数据存储的方式

    目录
    • js深拷贝
      • 数据存储方式
      • 什么是浅/深拷贝
      • 常用深拷贝实现
        • 1.通过JSON.stringify和JSON.parse
        • 2.扩展运算符
        • 3.手写递归深拷贝函数
    • 总结

      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)

      如何彻底掌握实现JavaScript深拷贝的多种方法?

      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; }

      总结

      本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注自由互联的更多内容!