更改初始对象的值后 Javascript 对象引用中断

标签 javascript javascript-objects shuffle slice

我试图理解我对 JavaScript 对象的困惑。具体来说,我感兴趣的是找出导致对象引用中断的原因(如果有的话)。

为了演示这一现象,我提供了一份 Chrome 的 JavaScript 控制台输出的副本。请注意,我在这里使用的是数组,但考虑到 JS 中数组和对象之间的细微差别,我们希望对象的行为相似。为了清楚起见,我添加了评论。

  // Set x to some array literal
> x = [1, 2, 3, 4, 5]
  [1, 2, 3, 4, 5]

  // Set y to x
> y = x
  [1, 2, 3, 4, 5]

> x
  [1, 2, 3, 4, 5] // as expected

> y
  [1, 2, 3, 4, 5] // as expected

如上所示,xy 都输出预期值。现在,我使用一个名为 shuffle 的函数(在这个问题的底部指定)来打乱 x 的值。

  // Shuffle x
> x = shuffle(x)
  [5, 1, 4, 2, 3]

> x
  [5, 1, 4, 2, 3] // x changes as expected

> y
  [5, 1, 4, 2, 3] // y changes as expected

同样,一切都按上面的预期工作。变量 xy 保持对同一对象的引用。然而,当我们重复这个操作时,结果却很奇怪。

  // Shuffle x
> x = shuffle(x)
  [3, 1, 5, 4, 2]

> x
  [3, 1, 5, 4, 2] // x changes as expected

> y
  [5, 1, 4, 2, 3] // y didn't change this time

下面是随机播放功能,改编自here .其目的是打乱数组的内容(参数 r1)并返回混合数组的前 n 项。

function shuffle(r1,n) {

  var i = r1.length, j, tempi, tempj, r2;
  r2 = r1;

  while (--i) {
    j = Math.floor(Math.random() * (i + 1));
    tempi = r2[i];
    tempj = r2[j];
    r2[i] = tempj;
    r2[j] = tempi;
  }

  return r2.slice(0,n);
}

我已经通过重写基于 this function 的洗牌函数解决了这个问题。 .但是,我仍然想了解发生了什么。为了快速查看运行中的代码,我制作了一个 jsFiddle .

有什么想法吗?感谢您的宝贵时间。

最佳答案

如果您删除 .slice(0,n);,它将按您预期的方式运行。 slice创建一个新数组。

所以第一次调用 shuffle 时,在循环中修改数组 x = y = r1 = r2。然后在最后一行复制它并将其分配给 x。现在 x !== y,但它们包含完全相同的元素。你可以test that they are distinct objects在您第一次调用随机播放之后:。

下次您调用 shuffle 时,您将对您制作的 x 的副本进行洗牌,而 y 保持不变。

关于更改初始对象的值后 Javascript 对象引用中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16258731/

相关文章:

javascript - 将元素从一个监听器传递到嵌套监听器

javascript - 内容安全策略 (CSP) : how to allow svg image in object

javascript - 我只想打印数组中的第一个值(名称)

python - 打乱数据框以计算 Pandas 中 P 值的最快方法

javascript - 如何将日期时间字符串转换为特定的日期时间格式

javascript - JS-洛达什;嵌套对象(父/子)到平面数组

javascript - 如何从路径(键数组)创建嵌套对象结构?

python - 使用 python 将 JavaScript 对象转换为 JSON

c++ - random_shuffle 修改打乱后的对象 (c++11)

c++ - 实现洗牌的逻辑