一个很常见的语法问题,但专注实现需求时经常会忘记去避免,导致最终问题的出现,再花时间排查。为此专门整理一篇解决方法的博客,也加强一下自己的记忆。
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:使用解构赋值仅用一行定义多个相同的数组,且指向堆不同(解构赋值)