You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数组中的对象是否按引用传递?解析洗牌函数中oldValue变量未随数组元素引用变更而改变的原因

关于JavaScript引用传递的两个疑问解答

嘿,我来帮你把这两个点掰明白——很多刚接触JS对象引用的朋友都会在这里卡壳,咱们一步步来:

1. 数组中的对象是否是按引用传递的?

首先得纠正一个常见误区:JavaScript里不存在真正的“按引用传递”,只有“按值传递”。不过对于对象(包括数组、普通对象)来说,这个“值”其实是指向内存中对象的引用地址。

所以数组里存储的并不是对象本身,而是对象的引用地址。当你把数组中的对象赋值给另一个变量,或者把数组作为参数传给函数时,传递的是这个引用地址的副本——也就是说,两个变量(或参数)会指向同一个对象,但它们本身是独立的变量,各自存着相同的引用值。

举个简单例子:

const arr = [{name: 'Alice'}];
const obj = arr[0];
obj.name = 'Bob';
console.log(arr[0].name); // 输出 'Bob'

这里obj和arr[0]都指向同一个对象,所以修改obj的属性会影响数组里的对象,但如果你给obj重新赋值一个新对象:

obj = {name: 'Charlie'};
console.log(arr[0].name); // 还是 'Bob',因为obj现在指向新对象,和arr[0]没关系了

2. 为什么洗牌代码里的oldValue没有跟着cards[newIndex]变化?

咱们盯着你的代码一步步拆解:

function shuffle(cards) {
  for (let i = cards.length - 1; i > 0; i --) {
    const newIndex = Math.floor(Math.random() * (i + 1));
    const oldValue = cards[newIndex]; 
    // 这一步:oldValue拿到的是cards[newIndex]当前存储的引用地址(比如指向{ suit: 'clubs', value: '5' })
    cards[newIndex] = cards[i]; 
    // 这一步:把cards[newIndex]这个数组位置的引用地址,换成了cards[i]的引用地址
    // 注意:这只是修改了数组里这个位置存的“地址纸条”,和oldValue手里的“地址纸条”没关系!
  }
}

你可以把引用地址想象成写着房间号的纸条:

  • 数组的每个位置就像一个盒子,里面装着一张写着房间号的纸条。
  • oldValue = cards[newIndex] 就是把盒子里的纸条抄了一份,oldValue现在手里有一张一模一样的纸条。
  • 然后你把盒子里的纸条换成了另一张(cards[newIndex] = cards[i]),但oldValue手里的那张抄件根本没动,它还是指向原来的房间。

所以oldValue不会跟着变化,因为它和数组的那个位置是两个独立的“容器”,只是曾经装过相同的引用地址而已。

总结一下:变量存储的是引用的副本,修改另一个容器里的引用,不会影响已经拷贝出去的引用值——只有当你通过引用修改对象本身的属性时,所有指向这个对象的变量才会看到变化。

内容的提问来源于stack exchange,提问作者PRMK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 20:07:41