从数组中删除不更新变量内的引用?

时间:2015-01-30 15:28:01

标签: javascript arrays object

通常更改对象/数组的引用,改变对象,反之亦然。

var someArr = [{letter: 'a'}, {letter: 'b'}, {letter: 'c'}];
var test = someArr[1];

test.letter = 'k';
// or
// someArr[1].letter = 'k'

console.log(test.letter); // outputs k
console.log(someArr[1].letter); // outputs k

如果所述索引的值发生变化,则对数组索引值(对象)的引用不会改变 - 例如如果通过splice删除该值,则引用将不会指向将其放在该索引处的新值。它仍然保留对删除值的引用。为什么呢?

var someArr = [{letter: 'a'}, {letter: 'b'}, {letter: 'c'}];
var test = someArr[1];

someArr.splice(1, 1); // remove object with letter b

console.log(test.letter); // outputs b <-- Why not c?
console.log(someArr[1].letter); // outputs c

这是一个JSFiddle http://jsfiddle.net/rf47jyxv/

我不想知道 就是这样。我知道就是这样。 我想知道为什么就是这样。

为什么在splice之后,变量test保留对someArr[1]的引用与直接调用someArr[1]不同?

3 个答案:

答案 0 :(得分:2)

someArr中的对象不同,并有自己的参考。您已将第二个对象的引用分配给test

因此,现在test具有第二个对象的引用,并且从数组中删除第二个对象并不会删除引用,正如您可能认为的那样,因为test仍然具有第二个对象的引用

拼接后,第三个对象取代第二个对象,因此someArr[1]{letter: 'c'},因此记录c

var someArr = [{letter: 'a'}, {letter: 'b'}, {letter: 'c'}];

// diff refs ------^--------------^---------------^ say r1, r2, r3 and r1 != r2 != r3

var test = someArr[1]; // r2

someArr.splice(1, 1); // you removed r2 in array but it is still being referred by test

console.log(test.letter); // outputs b as test, still has the r2 reference
console.log(someArr[1].letter); // outputs c, as it has r3 reference.

答案 1 :(得分:2)

变量test持有对象{letter: 'b'}的引用,该引用在某个时刻是someArray中的第二项。

答案 2 :(得分:1)

我看到你接受了答案(其他人都很好),但我想对发生的事情做一个额外的描述。

JavaScript中的数组不是它们出现的数组。 JavaScript数组基本上是一个美化的Javascript对象。 JavaScript中的数组引用/指向其他对象,它更像是带有顺序/增加键值的Map,而不是带有索引的数组。

所以在引擎盖下,数组someArr的第二个元素指向ram中其他位置的对象{letter:b}。创建值test时,它也指向该特定对象。对该对象的更改由数组someArr和var test反映。

当您通过splice(1,1)删除索引2处的引用时,数组someArr不再指向它。但是,test仍然指出了这一点。 (因此,在测试指向别的东西之前,它不会被垃圾收集)。

test未引用数组中的地址,test引用someArr创建test时指向的对象/地址。

以下阅读可能会有所帮助:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array https://javascriptweblog.wordpress.com/2010/07/12/understanding-javascript-arrays/