0

Don't understand why the code below is overwriting my var arr. Any help appreciated.

var arr = [1,2,3]

var string = "function swap(arr) { var newarr = arr; var temp = arr[0]; newarr[0] = arr[arr.length-1]; newarr[arr.length-1] = temp; return newarr }"

var test = eval("[" + string + "]")[0];

test(arr);
console.log(arr);
//this outputs [3,2,1]

test(arr);
console.log(arr);
//this outputs [1,2,3]

fiddle

Thanks

1
  • 6
    newarr = arr; means that newarr points to the same exact object as arr. So anything you do to newarr will be reflected in arr as well. You want newarr = arr.slice() to make a copy. Commented Apr 25, 2015 at 23:33

2 Answers 2

7

Because in JavaScript, objects are pass by reference value and arrays are objects. The eval is irrelevant here. Here is code producing the same issue without eval:

var arr = [1,2,3];
var arr2 = arr; // this just sets the reference
arr2[1] = 3; // this also changes arr
arr[0] = 3; // this also changes arr2
arr; // [3, 3, 3]
arr2; // [3, 3, 3]
Sign up to request clarification or add additional context in comments.

Comments

4

Why does this happen

JavaScript kind of has a thing where it creates references instead of copies. This can be useful, and annoying:

Where is it useful?

var self = this;

is a commonly used trick to trap the scope of a function.

var elem = document.getElementById('my_element');

is a way refer to elements as variables

When does this happen?

var arr = [1, 2, 3, 4];

var arr2 = arr;    //arr2 now references arr
var arr2[1] = 'd'; //Modifies arr2 and reference

console.log(arr2); //Line 6
console.log(arr);  //Line 7

This will give us:

[1, 'd', 3, 4] (line 6)

[1, 'd', 3, 4] (line 7)

In conclusion, this is just regular behavior of JavaScript!

What should I do?

To solve this, add

var arr2 = arr.slice();

.slice() returns a new version of the array. You can write your own function to do this by:

Array.prototype.clone = function () {
    return this.slice();
}

Now we can do:

var arr = [1, 2, 3, 4];

var arr2 = arr.clone(); //  Returns cloned arr
var arr2[1] = 'd';      //  Modifies arr2

console.log(arr2); //Line 6
console.log(arr);  //Line 7

This time:

[1, 'd', 3, 4] (line 6)

[1, 2, 3, 4] (line 7)

3 Comments

var arr2 = arr; does not create a reference - arr already is a reference.
@Pointy Ah yes, I see how that doesn't make sense
Adding things to Array.prototype (or Object.prototype for that matter) in this way will cause problems if you try to iterate through an array later. You should use Object.defineProperty to make it non-enumerable.

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.