4

I have the following problem with .push() method:

var myArray = ["a", "b", "c", "d"];

function add(arr) {
    arr.push("e");
    return arr;
}

add(myArray);

// myArray is now  ["a", "b", "c", "d", "e"]

Why it overrides myArray? Can't understand that...

2
  • See also: stackoverflow.com/questions/518000/… Commented Aug 29, 2010 at 22:28
  • I added an alternate solution. When you do .slice() you're having to make a copy of the array, store it, .push() the new value in, then return the copy. I've used .concat(), which will let you pass in the original array, and perform all the above steps at once. Commented Aug 29, 2010 at 22:59

2 Answers 2

9

Arrays in Javascript (and most other languages) are passed by reference.

When you write add(myArray), you are passing a reference to the same Array instance that the global myArray variable refers to.
Any changes to the array object will be visible through both references.

To copy the actual array instance, write add(myArray.slice());.
Note that this will not copy the objects inside of it.

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

6 Comments

Is there a simple way how to avoid that?
@Jany: you can't force an array to be passed by value - you'll have to copy it and then pass the copy as a reference, exactly as SLaks demonstrates.
You can pass a copy of the array by writing add(myArray.slice());
I think using slice method is very simple.
But if I write inside function arr = "";, myArray doesn't change. It hapens only with methods?
|
4

If you need to be able to nest arrays, then I'd change the .add() function to have the .concat() duplicate the Array into a variable, .push() the new value into the new Array, and return it.

function add(arr) {
    var newArr = arr.concat(); // duplicate
    newArr.push("e");      // push new value
    return newArr;         // return new (modified) Array
}

You could use concat() as well, and return the new array it creates.

var myArray = ["a", "b", "c", "d"];

function add(arr) {
    return arr.concat("e");
}
var newArray = add(myArray);

console.log( newArray );  // ["a", "b", "c", "d", "e"]
console.log( myArray );   // ["a", "b", "c", "d"]

So instead of two methods .slice() then .push(), you accomplish it with one .concat().

This also gives you the benefit of passing another Array instead of a string, so:

return arr.concat(["e","f"]);

would give you:

// ["a", "b", "c", "d", "e", "f"]

instead of:

// ["a", "b", "c", "d", ["e", "f"] ]

2 Comments

This is nice, thanks! But I need to put another array into... This doesn't work :( arr.concat([["e","f"]]);
@Jany - I updated my answer to .push() the value into the duplicate. You just pass the original Array into .add(), and it takes care of the duplication inside. This way, inside the .add() you have access to both Arrays, old and new.

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.