2014-01-14 72 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)