JS中的数组复制问题

前言

首先提到复制,也就是拷贝问题,就必须要明确浅拷贝和深拷贝。

  • 浅拷贝:B由A复制而来,改变B的内容,A也改变
  • 深拷贝:B由A复制而来,改变B的内容,A的内容不会改变

总的来说就是,基于引用对象的概念,浅拷贝拷贝的是地址,深拷贝直接对值进行了拷贝

那么在JS的数组中,哪些复制是浅拷贝的?哪些又是深拷贝的呢?这里做一个学习总结。

数组复制

直接赋值符号 “=” 复制

let arr1 = [2,3,4,5,6];
let arr2 = arr1;
arr2.push(12);
console.log(arr1); //[2, 3, 4, 5, 6, 12]
console.log(arr2); //[2, 3, 4, 5, 6, 12]

可以看到通过赋值符号 “=” 复制是浅拷贝。

扩展

数组属于引用数据类型,那么我们可以猜测,通过 赋值符号 “=” 赋值的引用数据类型的变量的复制都是浅拷贝,验证如下:

let obj1 = {value:23};
let obj2 = obj1;
obj2.value = 12;
console.log(obj1); //{value: 12}
console.log(obj2); //{value: 12}

那么值(基础)数据类型呢?

let num1 = 23;
let num2 = num1;
num2 = 12;
console.log(num1); //23
console.log(num2); //12

可以看到 基础数据类型通过赋值符号 “=” 的复制是深拷贝的,但要注意,如果你通过对象的方式进行定义的话,那么基础数据类型也会变成对象,对象的直接复制仅仅只复制了地址。

let num1 = new Number(23);
let num2 = num1;
num2 = 12;
console.log(num1); //23
console.log(num2); //12

数组中的复制函数

我们知道,js提供了很多数组复制的方法,例如拆分操作符(...),map函数,concat函数,slice函数,这些方法都可以进行数组的复制,那么今天就一起总结下哪些复制是浅拷贝的,哪些是深拷贝的。

let arr1 = [2,3,4,5,6];
arr2 = [...arr1];
arr2.shift();
console.log(arr1); //[2, 3, 4, 5, 6]
console.log(arr2); //[3, 4, 5, 6]

可以看到通过拆分操作符进行的复制是深拷贝的,arr2指向的是一个新的地址

let arr1 = [2,3,4,5,6];
arr2 = arr1.map(item=>item);
arr2.shift();
console.log(arr1); //[2, 3, 4, 5, 6]
console.log(arr2); //[3, 4, 5, 6]
let arr1 = [2,3,4,5,6];
arr2 = arr1.concat();
arr2.shift();
console.log(arr1); //[2, 3, 4, 5, 6]
console.log(arr2); //[3, 4, 5, 6]
let arr1 = [2,3,4,5,6];
arr2 = arr1.slice();
arr2.shift();
console.log(arr1); //[2, 3, 4, 5, 6]
console.log(arr2); //[3, 4, 5, 6]

经过验证,拆分操作符(...),map函数,concat函数,slice函数的复制均为深拷贝。

JS中的数组复制问题的更多相关文章

  1. js中的数组

    上网查了一下,js中的数组包含的内容还真不少.先给出两个学习的链接: w3school链接:http://www.w3school.com.cn/js/js_obj_array.asp 博客园链接:h ...

  2. JS中Array数组的三大属性用法

    原文:JS中Array数组的三大属性用法 Array数组主要有3大属性,它们分别是length属性.prototype属性和constructor属性. JS操作Array数组的方法及属性 本文总结了 ...

  3. JS中对数组元素进行增删改移

    在js中对数组元素进行增删改移,简单总结了一下方法: 方法 说明 实例 push( ); 在原来数组中的元素最后面添加元素 arr.push("再见58"); unshift( ) ...

  4. js中的数组遍历

    js中的数组遍历是项目中经常用到的,在这里将几种方法做个对比. ! for循环:使用评率最高,也是最基本的一种遍历方式. let arr = ['a','b','c','d','e']; for (l ...

  5. 遍历js中的数组

    可以使用js中的for循环,或者forEach方法:也可以使用Ext中的方法遍历js中的数组 代码如下: /** * 遍历数组 */ var arr = ['越南', '新加坡', '美国', '俄罗 ...

  6. java:JavaScript3(innerHTML,post和get,单选框,多选框,下拉列表值得获取,JS中的数组,JS中的正则)

    1.innerHTML用户登录验证: <!DOCTYPE> <html> <head> <meta charset="UTF-8"> ...

  7. js 中关联数组

    以前都不知道这种写法叫做关联数组. 何为关联数组呢.通常的数组在填充时会隐式或者显示指定数组下标,但JS中数组可以以名字的形式为元素赋值,这就形成了关联数组. 例子 var p={ name:'dai ...

  8. JavaScript学习笔记——JS中的变量复制、参数传递和作用域链

    今天在看书的过程中,又发现了自己目前对Javascript存在的一个知识模糊点:JS的作用域链,所以就通过查资料看书对作用域链相关的内容进行了学习.今天学习笔记主要有这样几个关键字:变量.参数传递.执 ...

  9. js中删除数组中某一项的方法

    1:js中的splice方法 splice(index,len,[item])    注释:该方法会改变原始数组. splice有3个参数,它也可以用来替换/删除/添加数组内某一个或者几个值 inde ...

随机推荐

  1. day17 生成器, 面向过程, 三元表达式, 生成式

    1. 生成器 生成器:就是一种自定义的迭代器,是用来返回多次值自定义迭代器的好处:节省内存 return只能返回一次值,函数就立即结束了yield 1.可以挂起函数,保存函数的运行状态 2.可以用来返 ...

  2. sql 增加修改表格属性字段

    1.修改字段默认值 alter table 表名 drop constraint 约束名字 ------注解:删除表的字段的原有约束 alter table 表名 add constraint 约束名 ...

  3. 智联家园-四大人工智能虚拟形象首秀MV

    2020 世界人工智能大会云端峰会在上海举行,由微软小冰作曲并携手其他 AI 演唱的 2020 世界人工智能大会云端峰会主题曲<智联家园> 今天正式发布,同时这也是小冰上海音乐学院毕业后的 ...

  4. LDAP注入介绍

    LDAP注入介绍 一. 前言 前些日子在看 OWASP TOP 10 时看到了对LDAP注入攻击的介绍,对此产生了兴趣,在网上经过一番搜索之后找到了构成本文主要来源的资料,整理出来分享给大家. 二. ...

  5. Mysql基础(二):MySQL之存储引擎

    目录 MySQL之存储引擎 1.MySQL存储引擎介绍 2.MySQL结构 3.MySQL存储引擎分类 4.存储引擎的使用 5.总结 MySQL之存储引擎 1.MySQL存储引擎介绍 MySQL中的数 ...

  6. 数据可视化实例(七): 计数图(matplotlib,pandas)

    https://datawhalechina.github.io/pms50/#/chapter5/chapter5 计数图 (Counts Plot) 避免点重叠问题的另一个选择是增加点的大小,这取 ...

  7. Linux 通过源代码安装和编译程序

    Linux源代码安装在平常工作学习中经常用到,总结下步骤↓↓↓ 第一步:#mount /dev/cdrom/mnt (挂载一个软盘) 第二步:手动安装httpd-2.4.25.tar.gz 依赖关系包 ...

  8. 学习jvm(一)--java内存区域

    前言 通过学习深入理解java虚拟机的教程,以及自己在网上的查询的资料,做一个对jvm学习过程中的小总结. 本文章内容首先讲解java的内存分布区域,之后讲内存的分配原则以及内存的监控工具.再下来会着 ...

  9. 题解 洛谷 P5311 【[Ynoi2011]成都七中】

    每次询问是关于 \(x\) 所在的连通块,所以考虑用点分树来解决本题. 点分树上每个节点所对应的子树,都是原树中的一个连通块.询问中给定 \(x\) 和区间 \([l,r]\),其就已经确定了原树的一 ...

  10. xshell如果通过跳板机登录其他机器

    首先,跳板机设置隧道 目标机器,选择刚才的隧道作为代理