2

Normally altering a reference to an object/array, alters the object and vice versa.

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

A reference to an array index' value (which is an object) won't change if the value of said index changes - e.g. if the value is removed via splice, the reference won't point to the new value that took it's place at that index. It still holds the reference to the removed value. Why?

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

Here is a JSFiddle http://jsfiddle.net/rf47jyxv/

I don't want to know that it is like that. I know it is like that. I would like to know why it is like that.

Why, after splice, is the variable test that holds a reference to someArr[1] different than calling someArr[1] directly?

5
  • at the second example: you've passed second element to a varibale and then you remove this second element from the array. so it's ok why test.letter gives b not c. Commented Jan 30, 2015 at 15:37
  • Well, I thought c is now the second element. Because it is from now on accessible with someArr[1] Commented Jan 30, 2015 at 15:38
  • with help of splice you remove the second so c becomes second element. the array is then truly altered. Commented Jan 30, 2015 at 15:40
  • yes and the reference to the second element does not reflect that. That's my problem. I know now that it is just is like that but it doesn't seem logical to me. Commented Jan 30, 2015 at 15:40
  • 1
    at the first example: in my console it prints k not h. Commented Jan 30, 2015 at 15:41

3 Answers 3

2

Variable test is holding a reference to object {letter: 'b'} which at some point was the second item in someArray.

Sign up to request clarification or add additional context in comments.

Comments

2

The objects in someArr are different, and have their own reference. You have assigned the reference of second object to test

So, now test has the reference of second object and removing the second objec from the array does not delete the reference, as you might think, because test still has the reference of second object intact.

After splicing, the third object takes place of second object, so someArr[1] is {letter: 'c'}, so it logs 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.

3 Comments

thank you for your answer. But it doesn't really answer why this is happening. You say yourself, after splicing the third object is available under the second reference someArr[1] - which is exactly what the variable test is holding. Yet, it outputs something else.
"someArr[1] - which is exactly what the variable test is holding" - no, variable test is holding a reference to object {letter: 'b'} which at some point was the second item in someArray
@Igor thanks that made it clear to me. test holds a reference to the object, not the index of the array. I'd accept that sentence as an answer if you care to write one.
1

I saw you accepted an answer (both the others are good), but I wanted to give an additional description of what is going on.

Arrays in JavaScript are not Arrays like they appear. JavaScript Arrays are basically a glorified Javascript Object. Array's in JavaScript reference/point to other objects, it is more of a Map with sequential/increasing key values instead of an Array with indexes.

So under the hood, the second element of your array someArr is pointing to an object {letter:b} somewhere else in ram. When you create your value test, it also points to that specific object. Changes to that object are reflected both by the Array someArr and by the var test.

When you remove the reference at index 2 via your splice(1,1), it no longer was pointed to by your Array someArr. However, it is still pointed to by test. (So at that, it is not going to get garbage collected until test points to something else).

test is not referencing the address in an array, test is referencing an object/address that someArr was pointing to when you created test.

The following reading might help more:

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

2 Comments

I didn't edit to say something different. I edited to add that test does not hold a reference to someArr[1], which is what I stated in my question. Anyways I appreciate your explanation - it helped too! +1
My apologies, will remove that statement from my response! Glad to hear the additional explanation helped :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.