js 两个相等的数组,为什么修改一个另外一个没有变化?

var a=[1,2,3,4,5]
var b=a
console.log(a) //输出[1,2,3,4,5]
console.log(b) //输出[1,2,3,4,5]

a=[]
console.log(a) //输出[]
console.log(b) //为什么这里会输出[1,2,3,4,5]?应该是随着a一起变成[]才对呀
阅读 2.6k
6 个回答

众所周知,函数 数组 对象 都是引用类型,不扯概念了

所以,你代码中的 a = [1,2,3,4,5] 改变的是 a 的引用,而不是对象本身, b = a 这个赋值操作是将 b 也指向 [1,2,3,4,5] 数组对象,之后 a = [] a 改变了它的引用,指向一个空数组对象,b 的指向自然跟 a 没关系啊

画个丑图,大概长这样,希望能帮助你理解

楼上说得对,var 有很多缺陷,es6 版本之后已经被let/const 代替,别再用了

1655798302226.png

大家都说了这么多,我只想请你思考一个问题:你修改的是「变量」还是「数组」。

扩展问题:

  • 变量是指什么
  • 数组又是指什么
  • 这两个东西有什么不同,又有什么联系
  • 从现象反推,是否可证实上述问题的答案

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。
a = 数组
b = a // b = 数组
a = 另一个数组 // 不关“数组”什么事

a = 数组
b = a
a[0] = 0 // 数组[0] = 0, b[0] = 0 这就对了

另外,请不要再用 var

// 定义a的引用
var a=[1,2,3,4,5]
// 将a的引用赋给B
var b=a
console.log(a) // 输出[1,2,3,4,5]
console.log(b) // 输出[1,2,3,4,5]
// a 变更引用对象
a=[]
console.log(a) // 输出[]
// 这个时候B的引用是最开始A赋给他的
console.log(b) // 输出[1,2,3,4,5]

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

可以这样理解,所谓传址是将一个数据结构的首地址赋予变量,所以b = a之后,b从a获取了一个内存首地址,仅此而已。b和a之间是完全无关的。

接下来,当访问变量时,如果变量指向了内存地址,那么就会得到该地址为首的完整数据结构。这才是b = a之后为什么看起来b和a一样的原因。

所以,对a赋值对不是a的任意变量均不产生任何影响,对一个数据结构的内容修改则相当于修改了某个内存地址的数据,所有覆盖了该地址的数据结构都可观察到响应的变化。

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏