js关于浅拷贝、深拷贝,数组的深拷贝

简介: 深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型。

🍀浅拷贝、深拷贝

深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型。
在这里插入图片描述
浅拷贝仅仅复制了指向某个对象的指针,并不复制对象本身,新对象与旧对象还是共享同一块内存,修改其中一个对象,另一个对象也会随之变化。
深拷贝会另外创造一个一模一样的对象,新对象跟旧对象不共享内存,修改其中一个对象不会影响到另一个对象。

在js当中,使用 ‘=’ 复制,就是js数组的浅拷贝。修改效果如下

var a=[1,0,0,8,6];
var b=a;
console.log(b);  //输出的是1,0,0,8,6
a[0]=5;
console.log(b);  //输出的是5,0,0,8,6

🍀实现数组的深拷贝

JSON.parse(JSON.stringify()) 方式

let arr = [5, 2, 9];
let arr2 = JSON.parse(JSON.stringify(arr));
arr2[2] = 0;
console.log(arr, arr2); // [5, 2, 9]  [5, 2, 0]

原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,这样可以生成新的对象,新对象会开辟新内存栈,实现深拷贝。

这种方法虽然可以实现数组或对象深拷贝,但不能处理函数。

递归生成

   // 定义检测数据类型的功能函数
   function checkedType(target) {
     return Object.prototype.toString.call(target).slice(8, -1)
   }
   // 实现深度克隆---对象/数组
   function clone(target) {
     // 判断拷贝的数据类型
     // 初始化变量result 成为最终克隆的数据
     let result, targetType = checkedType(target)
     if (targetType === 'object') {
       result = {}
     } else if (targetType === 'Array') {
       result = []
     } else {
       return target
     }
     // 遍历目标数据
     for (let i in target) {
       // 获取遍历数据结构的每一项值。
       let value = target[i]
       // 判断目标结构里的每一值是否存在对象/数组
       if (checkedType(value) === 'Object' ||
         checkedType(value) === 'Array') { 
          // 对象/数组里嵌套了对象/数组
          // 继续遍历获取到value值
         result[i] = clone(value)
       } else { 
         // 获取到value值是基本的数据类型或者是函数。
         result[i] = value;
       }
     }
     return result
   }

concat 方法
concat() 方法用于连接两个或多个数组。
该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。

let arr = [5, 2, 9];
let arr2 = arr.concat();
arr2[2] = 0;
console.log(arr, arr2); // [5, 2, 9]  [5, 2, 0]

slice 方法

slice() 方法可从已有的数组中返回选定的元素。arrayObject.slice(start,end)方法返回一个新的数组,包含从 start 到 end (不包括该元素,数学上来讲是左闭右开,即包含左,不含右)的 arrayObject 中的元素。

let arr = [5, 2, 9];
let arr2 = arr.slice(0);
arr2[2] = 0;
console.log(arr, arr2); // [5, 2, 9]  [5, 2, 0]

ES6扩展运算符

...扩展运算符是ES6的语法。
但是需要注意的是:用扩展运算符对数组或者对象进行拷贝时,只能扩展和深拷贝第一层的值,对于第二层极其以后的值,扩展运算符将不能对其进行打散扩展,也不能对其进行深拷贝,即拷贝后和拷贝前第二层中的对象或者数组仍然引用的是同一个地址,其中一方改变,另一方也跟着改变。

let arr = [5, 2, 9,{
   name: ' kobe'
}];
let [...arr2] = arr;
arr2[2] = 0;
arr2[3].name = 'tom';
console.log(arr, arr2);

在这里插入图片描述

目录
相关文章
|
4月前
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
4月前
|
数据采集 JavaScript 前端开发
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
用array.filter()来实现数据筛选、数据清洗和链式调用,相对于for循环更加清晰,语义化强,能显著提升代码的可读性和可维护性。博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
9月前
|
自然语言处理 前端开发 JavaScript
🛠️ JavaScript数组操作指南:20个精通必备技巧🚀
本文详细介绍了 JavaScript 中的 20 个高效数组操作技巧,涵盖了从基本的添加、移除元素,到数组转换和去重等高级操作。强调了不可变性的重要性,提供了清晰的代码示例,帮助开发者编写更整洁和高效的代码。无论是新手还是经验丰富的开发者,这些技巧都将显著提升您的编码能力,使您在项目中更具竞争力。
101 2
|
9月前
|
JavaScript 前端开发
JavaScript中的深拷贝与浅拷贝
JavaScript中的深拷贝与浅拷贝
89 4
|
9月前
|
JavaScript 前端开发 测试技术
JS都有哪些操作数组的方法
JS都有哪些操作数组的方法
121 3
|
9月前
|
JavaScript
js删除数组中已知下标的元素
js删除数组中已知下标的元素
110 4
|
9月前
|
缓存 JavaScript 前端开发
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
130 1
|
9月前
|
JavaScript 前端开发 API
JS中数组的方法flat()怎么用
JS中数组的方法flat()怎么用
110 0
|
9月前
|
JavaScript 前端开发 索引
JavaScript中数组、对象等循环遍历的常用方法介绍(一)
JavaScript中数组、对象等循环遍历的常用方法介绍(一)
141 0
|
9月前
|
前端开发 JavaScript 索引
JavaScript 数组常用高阶函数总结,包括插入,删除,更新,反转,排序等,如map、splice等
JavaScript数组的常用高阶函数,包括遍历、插入、删除、更新、反转和排序等操作,如map、splice、push、pop、reverse等。
178 0

热门文章

最新文章