2014-01-14 26 views
2

我不希望foo在这个例子中改变,但是当我在函数中将它修改为数组时,它会改变参数。注意foo不会被function1改变...我猜是因为它不直接修改参数?任何帮助避免这将不胜感激。为什么我的函数在修改数组时改变参数?

http://jsfiddle.net/t47kD/

var foo = [1,2,3]; 

bar = function1(foo); 
bar = function2(foo); 
bar = function3(foo); 


function function1(newFoo){ 
    newFoo = [newFoo,'a',1]; 
    return newFoo; 
} //foo after function1 = 1,2,3 


function function2(newFoo){ 
    newFoo[0] = 'a'; 
    return newFoo; 
} //foo after function2 = a,2,3 


function function3(newFoo){ 
    newFoo.push('4'); 
    return newFoo; 
} //foo after function3 = a,2,3,4 

回答

1

对象(包括数组)在ECMAScript中通过引用进行分配。因此,当您在函数中修改数组时,您正在修改与传入函数相同的数组,而不是数组的新副本。

快速执行数组浅表副本的方法是使用slice(0)(在某些现代引擎中,您可以省略0)。有关复制数组,请参阅this answer

另外参见this answer的一些例子。

0

当传递数组给一个函数,它通过参考。在函数2和函数3中,您正在修改foo数组。在功能1,newFoo将与第一项是foo,则值a和1

1
var foo = [1,2,3]; 

bar = function1(foo); 
bar = function2(foo); 
bar = function3(foo); 


function function1(newFoo){ 
    return [newFoo,'a',1]; 
} //foo after function1 = 1,2,3 


function function2(newFoo){ 
    var otherFoo = newFoo.slice(0); 

    otherFoo[0] = 'a'; 
    return otherFoo; 
} //foo after function2 = 1,2,3 


function function3(newFoo){ 
    var otherFoo = newFoo.slice(0); 

    otherFoo.push('4'); 
    return otherFoo; 
} //foo after function2 = 1,2,3 
1

在功能2和功能3,你正在修改的输入变量(通过改变它的内容)由阵列组成。

在函数1中,您并未修改输入变量;你只是将它分配给指向=的其他东西。

对象(包括数组)通过引用传递 - 如果不想修改输入,最安全的做法是在函数的开头复制输入(在可能修改它之前)。对于阵列,您可以使用slice函数执行此操作:var copy = input.slice(0)