# Javascript object reference breaks after changing initial object's value

### Tags:

#### shuffle

I am trying to understand a point of confusion I have with JavaScript objects. Specifically, I am interested in finding what, if anything, causes an object reference to break.

To demonstrate the phenomenon, I have included a copy of some output from Chrome's JavaScript console. Note that I am working with arrays here, but we would expect objects to behave similarly given the subtle distinction between arrays and objects in JS. I have added comments for clarity.

``````  // 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
``````

As demonstrated above, both `x` and `y` output the expected value. Now I shuffle the values of x using a function called `shuffle` (specified at the bottom of this question).

``````  // 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
``````

Again, everything works as expected above. The variables `x` and `y` have maintained reference to the same object. However, when we repeat this operation, the results are strange.

``````  // 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
``````

Below is the shuffle function, adapted from here. Its purpose is to shuffle the contents of an array (parameter `r1`) and to return the first `n` items of the mixed array.

``````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);
}
``````

I have since fixed the problem by rewriting my shuffle function based on this function. However, I would still like to understand what's going on. For a quick look at the code in action, I have made a jsFiddle.

Any ideas? I appreciate your time.

613

#### chrisfargen

If you remove the `.slice(0,n);`, it will behave the way you expect. slice makes a new array.

So the first time you call shuffle, within your loop you modify the array `x = y = r1 = r2`. Then you make a copy of it on that last line and assign that to x. Now `x !== y`, but they contain the exact same elements. You can test that they are distinct objects after your first call to shuffle:.

The next time you call shuffle you are shuffling the copy of `x` you made and `y` is untouched.

174

#### Paul

`.slice()` makes a shallow copy of the Array, and so you're overwriting `x` with a new Array.

``````// The original was shuffled, but now `x` is a new Array
x = shuffle(x);
``````

That's why `y` showed the first shuffle (because you hadn't sliced it yet), but none thereafter. The subsequent shuffle was on the overwritten `x`, and `y` still references the original.

If you wanted to truncate the original Array, just change its `.length`.

``````return r2.slice(0,n);
``````

Do this:

``````r2.length = n;
``````

...though you're not passing anything to `n` currently.

35