JS005. 拷贝引用数据类型Array使其指向不同堆的解决方案
一个很常见的语法问题,但专注实现需求时经常会忘记去避免,导致最终问题的出现,再花时间排查。为此专门整理一篇解决方法的博客,也加强一下自己的记忆。
TAG: JSON.parse() JSON.stringify() Array.prototype.concat() 扩展运算符 Object.assign()
案例复现
左右变量皆为数组的等式,它们所指向的堆栈也会相同。
- let arrA = [1, 2, 3]
- let arrB = arrA
- arrA.pop()
- console.log(arrB)
- // [1, 2]
问题原因
JS中array是引用类型,也就是arrA和arrB的原数据存储地址是一样的,arrA和arrB都是对原数据的引用,所以修改其中一个,另一个也会改变。
就好像是一个房间有两扇门,AB两人分别从不同的门进去所到达的房间是一样的,此时A拿走一个苹果,B会看到房间里少了一个苹果;B从外面带了一瓶饮料回到房间,A也会看到这个房间多了一瓶饮料。
解决方案
- ES6 - Object.assign( )
Object.assign( )
方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。它的第一个参数是目标对象,后面的参数都是源对象。
- let arrA = [1, 2, 3]
- let arrB = Object.assign([], arrA)
- arrA = null
- console.log(arrB)
- // [1, 2, 3]
- ES6 - 扩展运算符
对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中,数组同理。
- let arrA = [1, 2, 3]
- let arrB = [...arrA]
- arrA.pop()
- console.log(arrB)
- // [1, 2]
- Array对象 - concat( )
concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。
- let arrA = [1, 2, 3]
- let arrB = [].concat(arrA)
- arrA.shift()
- console.log(arrA, arrB)
- // [2, 3][1, 2, 3]
- JavaScript JSON - JSON.stringify( ) & JSON.parse( )
JSON.stringify( ) 方法用于将 JavaScript 值转换为 JSON 字符串。
JSON.parse( ) 方法用于将一个 JSON 字符串转换为对象。
- let arrA = []
- let arrB = JSON.parse(JSON.stringify(arrA))
- arrA.push(1)
- console.log(arrA, arrB)
- // [1][]
我的其他相关文章:
ES6:使用解构赋值仅用一行定义多个相同的数组,且指向堆不同(解构赋值)
- END -
JS005. 拷贝引用数据类型Array使其指向不同堆的解决方案的更多相关文章
- JS基本数据类型和引用数据类型的区别及深浅拷贝
前言 首先我们先来了解一下什么叫栈堆,基本数据类型与引用数据类型 1.栈(stack)和堆(heap)stack为自动分配的内存空间,它由系统自动释放:而heap则是动态分配的内存,大小也不一定会自动 ...
- Object 对象(对象的分类、属性(属性名和属性值)、基本数据类型与引用数据类型区别)
Object——引用数据类型 基本数据类型的不足之处:基本数据类型是单一的值,不能表现出值与值之间的所属关系 object分为内建对象.宿主对象和自定义对象 a 内建对象:ES标准中定义的对象,在任何 ...
- [19/05/28-星期二] JavaScript_ 对象和引用数据类型
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- js数组和对象相等判断、拷贝详解(结合几个现象讲解引用数据类型的趣事)
序言 最近遇到几个js引用数据类型造成的bug,今天结合bug详细分析一下,避免以后再犯,也希望能帮大家提个醒,强化js基本功. 目录 1.浅拷贝.深拷贝,解决变量赋值相互影响问题 2.判断2个数组. ...
- java基础-引用数据类型之一维数组(Array)
java基础-引用数据类型之一维数组(Array) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数组的定义 1>.为什么需要数组 保存一个数据可以定义一个变量,如果要保 ...
- java基础-引用数据类型之二维数组(Array)
java基础-引用数据类型之二维数组(Array) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 之前我们学习过了Java的一维数组,所谓的二维数组就是元素是一堆一维数组的数组,换 ...
- (vue.js)vue中引用了别的组件 ,如何使this指向Vue对象
Vue中引用了别的组件 ,如何使this指向Vue对象 今天学习Vue组件传值, 通过创建Vue实例, 广播和监听实现传值, 但是传值之后无法直接将得到的值应用到Vue对象, 因为这相当于引用改了别的 ...
- JS 基本数据类型和引用数据类型
本文章已收录于: .embody { padding: 10px 10px 10px; margin: 0 -20px; border-bottom: solid 1px #ededed } .e ...
- JavaScript中基本数据类型和引用数据类型的区别
1.基本数据类型和引用数据类型 ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型. 基本数据类型指的是简单的数据段,引用数据类型指的是有多个值构成的对象. 当我们把变量赋值给一个变 ...
随机推荐
- Vue学习笔记(二)动态绑定、计算属性和事件监听
目录 一.为属性绑定变量 1. v-bind的基本使用 2. v-bind动态绑定class(对象语法) 3. v-bind动态绑定class(数组语法) 4. v-bind动态绑定style(对象语 ...
- DASCTF七月赛两道Web题复现
Ezfileinclude(目录穿越) 拿到http://183.129.189.60:10012/image.php?t=1596121010&f=Z3F5LmpwZw== t是时间,可以利 ...
- [CISCN2019 华北赛区 Day2 Web1]Hack World(二分法写布尔注入脚本)
记一道布尔注入的题,存在过滤字符. 从题目看应该是一道注入题.提示存在flag表flag列. 输入1和2的返回结果不一样,可能是布尔注入. 简单用万能密码尝试了一下.提示SQL Injection C ...
- Android系统编程入门系列之服务Service齐头并进多线程任务
在上篇文章中初步了解了Android系统的四大组件之一的服务Service,在服务内可以执行无用户交互的耗时操作任务,但是包括之前关于界面系列文章在内,生命周期方法都是在主线程内被系统回调的.如果直接 ...
- Docker部署netcore web实践
1. 新建一个netcore的项目 2. 我们到项目的生成输出目录下,创建一个Dockerfile文件 3. 编辑Dockerfile文件 备注:红线圈住的地方,就是你生成的netcore的程序名称 ...
- Build Puppet Clusters with Vagrant
$ cd ~/docs/propuppetex/chapter3 $ cat Vagrantfile Vagrant.configure(VAGRANTFILE_API_VERSION) do |co ...
- SQL语法 - WHERE 子句
WHERE 子句用于规定选择的标准. 语法 SELECT 列名称 FROM 表名称 WHERE 列 运算符 值 下面的运算符可在 WHERE 子句中使用: 操作符 描述 = 等于 <> 不 ...
- Longhorn 企业级云原生分布式容器存储-券(Volume)和节点(Node)
内容来源于官方 Longhorn 1.1.2 英文技术手册. 系列 Longhorn 是什么? Longhorn 云原生分布式块存储解决方案设计架构和概念 Longhorn 企业级云原生容器存储解决方 ...
- Linux学习手册
入门概述 Linux 简介 Linux 内核最初只是由芬兰人林纳斯·托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写的. Linux 是一套免费使用和自由传播的类 Unix ...
- Ubuntu完全卸载Docker步骤
Ubuntu完全卸载Docker步骤:https://www.jianshu.com/p/c03044dbeaaf