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一起变成[]才对呀
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一起变成[]才对呀
大家都说了这么多,我只想请你思考一个问题:你修改的是「变量」还是「数组」。
扩展问题:
已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。
a = 数组
b = a // b = 数组
a = 另一个数组 // 不关“数组”什么事
a = 数组
b = a
a[0] = 0 // 数组[0] = 0, b[0] = 0 这就对了
另外,请不要再用 var
了
你修改的是变量,修改的不是数组
一把钥匙开一把锁,钥匙撅断了,锁也不会那么深情的一起坏掉
已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。
// 定义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 周年「问答」打卡 ,欢迎正在阅读的你也加入。
8 回答4.7k 阅读✓ 已解决
6 回答3.4k 阅读✓ 已解决
5 回答2.8k 阅读✓ 已解决
5 回答6.3k 阅读✓ 已解决
4 回答2.2k 阅读✓ 已解决
4 回答2.8k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
众所周知,函数 数组 对象 都是引用类型,不扯概念了
所以,你代码中的
a = [1,2,3,4,5]
改变的是 a 的引用,而不是对象本身,b = a
这个赋值操作是将 b 也指向[1,2,3,4,5]
数组对象,之后a = []
a 改变了它的引用,指向一个空数组对象,b 的指向自然跟 a 没关系啊画个丑图,大概长这样,希望能帮助你理解
楼上说得对,var 有很多缺陷,es6 版本之后已经被let/const 代替,别再用了