Javascript对象引用在更改初始对象后中断's值
Javascript object reference breaks after changing initial object's value
我试图理解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
如上所述,x
和y
都输出期望值。现在,我使用一个名为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
同样,一切都如上面所预期的那样。变量x
和y
保持对同一对象的引用。然而,当我们重复这个操作时,结果却很奇怪。
// 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
下面是根据此处改编的shuffle函数。其目的是打乱数组的内容(参数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);
}
从那以后,我通过基于这个函数重写shuffle函数来解决这个问题。然而,我仍然想了解发生了什么。为了快速了解代码的运行情况,我制作了一个jsFiddle。
有什么想法吗?我很感激你抽出时间。
如果删除.slice(0,n);
,它将按照您期望的方式运行。slice生成一个新数组。
因此,第一次调用shuffle时,在循环中修改数组x = y = r1 = r2
。然后在最后一行复制它,并将其分配给x。现在是x !== y
,但它们包含完全相同的元素。您可以在第一次调用shuffle后测试它们是否是不同的对象:。
下次调用shuffle时,您正在对您制作的x
副本进行shuffle操作,而y
未受影响。
.slice()
制作了一个Array的浅层副本,因此您正在用一个新的Array覆盖x
。
// The original was shuffled, but now `x` is a new Array
x = shuffle(x);
这就是为什么y
显示了第一次shuffle(因为您还没有对其进行切片(,但之后没有。随后的混洗是在被覆盖的x
上进行的,并且y
仍然引用原始的。
如果要截断原始数组,只需更改其.length
即可。
因此,取而代之的是:
return r2.slice(0,n);
这样做:
r2.length = n;
尽管您当前没有向n
传递任何内容。
- 引用对象中的通用值
- jQuery匹配JSON对象的部分文本
- 节点导出返回一个空对象
- 如何在Javascript中将JSon对象转换为数组
- 我可以在json对象中添加一个函数吗
- 使用JS将数组转换为json对象
- 全局变量和全局对象的属性之间有什么区别吗
- 比较从函数和生成的日期对象
- Javascript,访问一个主要对象模块模式中的每个对象
- 包含数组的对象的QML ListModel追加中断
- 循环对象的顺序只能在迭代期间中断
- 我的 JS 对象迭代在添加新属性时中断
- 当我尝试在jquery mobile中使用对象方法时的代码中断
- Javascript对象比较递归中断
- 通过 $.post() 将 HTML 元素传递给 PHP 会返回 JavaScript 对象或中断:我必须如何编码它
- 使用append()移动对象后,jQuery侦听器目标似乎中断了
- Javascript对象引用在更改初始对象后中断's值
- 当我用对象文字添加原型属性时,上游直接原型属性就会中断.为什么?
- 无法使用$.Defered()对象和$.then()中断递归
- Javascript -使用下拉来瞄准对象属性在第一次使用后中断