Javascript Eval覆盖变量

时间:2015-04-25 23:31:51

标签: javascript eval

不明白为什么下面的代码会覆盖我的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]

fiddle

由于

2 个答案:

答案 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行)