不明白为什么下面的代码会覆盖我的var arr。任何帮助赞赏。
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]
由于
答案 0 :(得分:7)
因为在JavaScript中,对象通过引用值传递,而数组是对象。评估与此无关。以下代码产生相同的问题而没有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]
答案 1 :(得分:4)
JavaScript类似于创建引用而不是副本。这可能很有用,也很烦人:
哪里有用?
var self = this;
是捕获函数范围的常用技巧。
var elem = document.getElementById('my_element');
是一种将元素称为变量的方式
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
这将给我们:
[1,'d',3,4](第6行)
[1,'d',3,4](第7行)
总之,这只是JavaScript的常规行为!
要解决此问题,请添加
var arr2 = arr.slice();
.slice()
返回数组的 new 版本。您可以编写自己的函数来执行此操作:
Array.prototype.clone = function () {
return this.slice();
}
现在我们可以做到:
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
这一次:
[1,'d',3,4](第6行)
[1,2,3,4](第7行)