数组和对象的地址引用问题

前言:大家在使用js数组的时候,特别是进行二次复制,然后把临时变量做修改的时候,发现原数组值也被修改了,这时候其实就是一个地址引用的问题。本次就是为大家解释一下发生的几种情况和解决方案

第一种

var a = [1,2,3,4]

var b = a

b[0] = 5

console.log(a)

[5,2,3,4]

解释:

JS中是没有指针概念,只有传值、传址(引用)的两种情况

所以可以分析

var a = [1,2,3,4]

#a 代表的不只是一个数组,也是一个数组对象,那么a其实就是[1,2,3,4]的地址

那么同样

var b = a

var c = b

var ...

#都是对 [1,2,3,4]的地址使用,并非开一个新的空间

#所以就会产生如下情况

b[0] = 5

#实际修改的是 [1,2,3,4] 的第一个值

解决:

var a = [1,2,3,4]

var b = [].concat(a)

b[0] = 5

console.log(a)

[1, 2, 3, 4]

解释:

concat() 方法用于连接两个或多个数组。

该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。所以再使用的时候就不是a的地址了

主要针对是一维数组的情况

第二种,使用值的情况

var b = a[0]

b = 8

console.log(a)

[5,2,3,4]

解释:

从上面代码分析,把a索引为0的值,给了b,这时候的b其实用的就是真实的值,并非是一个整体对象,所以在修改b的值时候,不会影响到a所有的数据

第三种,数组内容是对象的时候

var a = [,]

var b = [].concat(a)

b[0][1] = 3

#再打印a

0:

1:

#这时候发现,concat并未启到作用,

解释:

其实这本质还是改变了地址,因为本身就是对象,只是放到了数组中,那么connat复制的是第一层,没有针对内容的对象进行重新生成新的值。

解决:

var b = JSON.parse(JSON.stringify(a))

b[0][1] = 3

#再打印a

0:

1:

#JSON.stringify 是将内容转成了字符串,那么就消除了对象地址那一个层级。这时候再解析成对象,那么就是新的空间了

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200430A05CE400?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券