一个很常见的语法问题,但专注实现需求时经常会忘记去避免,导致最终问题的出现,再花时间排查。为此专门整理一篇解决方法的博客,也加强一下自己的记忆。

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][]

我的其他相关文章:

JS004. 获取数组最后一个元素且不改变数组的四种方法

ES6:使用解构赋值仅用一行定义多个相同的数组,且指向堆不同(解构赋值)

- END -

JS005. 拷贝引用数据类型Array使其指向不同堆的解决方案的更多相关文章

  1. JS基本数据类型和引用数据类型的区别及深浅拷贝

    前言 首先我们先来了解一下什么叫栈堆,基本数据类型与引用数据类型 1.栈(stack)和堆(heap)stack为自动分配的内存空间,它由系统自动释放:而heap则是动态分配的内存,大小也不一定会自动 ...

  2. Object 对象(对象的分类、属性(属性名和属性值)、基本数据类型与引用数据类型区别)

    Object——引用数据类型 基本数据类型的不足之处:基本数据类型是单一的值,不能表现出值与值之间的所属关系 object分为内建对象.宿主对象和自定义对象 a 内建对象:ES标准中定义的对象,在任何 ...

  3. [19/05/28-星期二] JavaScript_ 对象和引用数据类型

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. js数组和对象相等判断、拷贝详解(结合几个现象讲解引用数据类型的趣事)

    序言 最近遇到几个js引用数据类型造成的bug,今天结合bug详细分析一下,避免以后再犯,也希望能帮大家提个醒,强化js基本功. 目录 1.浅拷贝.深拷贝,解决变量赋值相互影响问题 2.判断2个数组. ...

  5. java基础-引用数据类型之一维数组(Array)

    java基础-引用数据类型之一维数组(Array) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数组的定义 1>.为什么需要数组 保存一个数据可以定义一个变量,如果要保 ...

  6. java基础-引用数据类型之二维数组(Array)

    java基础-引用数据类型之二维数组(Array) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 之前我们学习过了Java的一维数组,所谓的二维数组就是元素是一堆一维数组的数组,换 ...

  7. (vue.js)vue中引用了别的组件 ,如何使this指向Vue对象

    Vue中引用了别的组件 ,如何使this指向Vue对象 今天学习Vue组件传值, 通过创建Vue实例, 广播和监听实现传值, 但是传值之后无法直接将得到的值应用到Vue对象, 因为这相当于引用改了别的 ...

  8. JS 基本数据类型和引用数据类型

    本文章已收录于:   .embody { padding: 10px 10px 10px; margin: 0 -20px; border-bottom: solid 1px #ededed } .e ...

  9. JavaScript中基本数据类型和引用数据类型的区别

    1.基本数据类型和引用数据类型 ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型. 基本数据类型指的是简单的数据段,引用数据类型指的是有多个值构成的对象. 当我们把变量赋值给一个变 ...

随机推荐

  1. Java8 Lambda表达式(一)

    目录 一.应用场景引入 优化一:使用策略模式 优化二:使用匿名内部类 优化三:使用Lambda表达式 优化四:使用Stream API 二.Lambda运算符和对应语法 语法格式 Lambda表达式需 ...

  2. 学废了系列 - WebGL与Node.js中的Buffer

    WebGL 和 Node.js 中都有 Buffer 的使用,简单对比记录一下两个完全不相干的领域中 Buffer 异同,加强记忆. Buffer 是用来存储二进制数据的「缓冲区」,其本身的定义和用途 ...

  3. MySQL 优化特定类型的查询

    优化COUNT()查询 COUNT() 是一个特殊的函数,有两种非常不同的作用: 统计某个列值的数量,也可以统计行数.在统计列值时要求列值是非空的(不统计NULL ).如果在COUNT() 的括号中指 ...

  4. PaddlePaddle之猫狗大战(本地数据集)

    新手入门PaddlePaddle的一个简单Demo--猫狗大战 主要目的在于整体了解PP用卷积做图像分类的流程,以及最最重要的掌握自定义数据集的读取方式 猫狗数据集是从网络上下载到工作目录的. 本项目 ...

  5. 在Ant脚本中使用时间戳

    时间戳在项目自动构建中广泛使用,例如在jar文件的manifest文件中,以及最后zip包的文件名里等,时间戳对应的Ant命令是,这个标签既可以用在一个内部,也可以放在外部用作"全局&quo ...

  6. 管理员权限的窗口,收不到WM_COPYDATA

    windows用户界面特权隔离 一个运行在较低特权等级的应用程序的行为就受到了诸多限制,它不可以: 验证由较高特权等级进程创建的窗口句柄 通过调用SendMessage和PostMessage向由较高 ...

  7. CSS Transform完全指南 #flight.Archives007

    Title/ CSS Transform完全指南 #flight.Archives007 序: 第7天了! 终身学习, 坚持创作, 为生活埋下微小的信仰. 我是忘我思考,共同进步! 简介: 一篇最简约 ...

  8. SpringBoot开发二十四-Redis入门以及Spring整合Redis

    需求介绍 安装 Redis,熟悉 Redis 的命令以及整合Redis,在Spring 中使用Redis. 代码实现 Redis 内置了 16 个库,索引是 0-15 ,默认选择第 0 个 Redis ...

  9. 附件携马之CS免杀shellcode过国内主流杀软

    0x01 写在前面 其实去年已经写过类似的文章,但是久没用了,难免有些生疏.所谓温故而知新,因此再详细的记录一下,一方面可以给各位看官做个分享,另一方面等到用时也不至于出现临阵磨枪的尴尬场面. 0x0 ...

  10. 【工作篇】再次熟悉 SpringMVC 参数绑定

    前言 主要现在项目中使用的参数绑定五花八门的,搞得很头大,例如有些用字符串接收日期,用字符串接受数组等等,完全没有利用好 SpringMVC 的优势,这里自己也总结一下,免得到时又要百度谷歌查找. 以 ...