javascript pass by reference workaround

let's say I've got an array, var animals = ["dog","cat","rat"];

then I define var pets = animals;

then I call pets.shift();

now because javascript is pass-by-reference for arrays, if I now call animals, I get ["cat","rat"].

My question: is there any way around this, if I would later like to use animals in its unmodified form?

Answers:

Answer

A note on terminology: JavaScript is never pass-by-reference (no matter how many times you hear people say that it is). When you write the line:

var pets = animals;

You're assigning the value of animals to pets. The value that is assigned is a reference to an array, so now both variables refer to the same object in memory. (Note: this is a bit pedantic, but it also has the nice property of being correct.)

If you want these two variables to refer to two different arrays, then you need to create a copy of the original array and assign a reference to that to pets. The most common way to do that in JavaScript is to take advantage of the fact that some array methods (like slice or concat) create a copy of the array on which they're called:

var pets = animals.concat();

Proof of in/equality:

var arr = [];
arr1 = arr;
console.log(arr1 === arr); // true
console.log(arr1 === arr.concat()) // false

Of course, you can also perform the copy yourself:

function copy(arr) {
    var i, len = arr.length, arr1 = new Array(len);
    for (i = 0; i < len; i += 1) {
        arr1[i] = arr[i];
    }
    return arr1;
}

Indeed, this is probably a lot faster and should be considered for very large arrays. (In most cases, just do whatever is most readable.)

Note that each of these methods creates a shallow copy of the original array. If the array holds references to other objects, then those references are copied to the new array (i.e. both the original and the new array will refer to the same objects). Strings and numbers, on the other hand, are copied directly into the new array.

Answer

You have to clone the array, which is done with

var savedAnimals = animals.slice();

Note that this isn't a deep clone : it doesn't protect the elements inside against modification (if they're not strings).

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.