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
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]
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)