2015-04-06 41 views
2

我一直在考虑下面的虚拟分配了解范围和易变性在JavaScript:参数的范围和对象可变性在javascript

对于这个练习,写两个功能,reverseArray和reverseArrayInPlace。第一个reverseArray将一个数组作为参数,并生成一个具有相反元素的新数组。第二个reverseArrayInPlace函数完成reverse方法的作用:它修改给定的数组作为参数,以便反转它的元素。既不可以使用标准的反向方法。

我编写了reverseArray函数成功编译并希望重用它用于reverseArrayInPlace函数。我编写了3个版本的函数,我真的不明白为什么有些工作,而有些则没有。我将不胜感激任何有关此JavaScript行为的解释。 (我知道有其他方法来解决reverseArrayInPlace,但我想知道为什么我的方法不工作)。

// Reverses an array given as argument and returns it as a NEW array. 
function reverseArray(myArray){ 
    var reversedArray = []; 
    for(var i=0; i<myArray.length; i++){ 
     reversedArray.unshift(myArray[i]); 
    } 
    return reversedArray; 
} 

/* 
    Reverse the original array in place 
*/ 

// DOESN'T WORK 
function reverseArrayInPlace1(myArray){ 
    myArray = reverseArray(myArray); 
} 

// DOESN'T WORK 
function reverseArrayInPlace2(myArray){ 
    var original = []; 
    for (var i=0; i<myArray.length; i++) { 
     original[i]=myArray[i]; 
    } 
    myArray = reverseArray(original); 
} 

// WORKS 
function reverseArrayInPlace3(myArray){ 
    var original = []; 
    for (var i=0; i<myArray.length; i++) { 
     original[i]=myArray[i]; 
    } 
    var newArray = reverseArray(original); 
    for (var i=0; i<myArray.length; i++) { 
     myArray[i]=newArray[i]; 
    } 
} 

miArreglo = ["a", "b", "c", "d" ]; 
console.log("MyArray: ", miArreglo); 

arregloRever=reverseArray(miArreglo); 
console.log("Reversed using reverseArray: ", arregloRever); 

reverseArrayInPlace1(miArreglo); 
console.log("Reversed using reverseArrayInPlace1: ",miArreglo); 

reverseArrayInPlace2(miArreglo); 
console.log("Reversed using reverseArrayInPlace2: ",miArreglo); 

reverseArrayInPlace3(miArreglo); 
console.log("Reversed using reverseArrayInPlace3: ",miArreglo); 
+2

请参阅此处了解为什么“不起作用”部分不起作用的解释:http://stackoverflow.com/questions/13506398/why-are-objects-values-captured-inside-function-calls/13508654#13508654 – slebetman 2015-04-06 03:03:12

回答

2

reverseArrayInPlace1reverseArrayInPlace2不工作,因为参数通过值在JavaScript中通过。 myArray是本地函数,并重新分配它不会影响调用者。

您可以采取相反的方法来重用您的代码,并根据reverseArrayInPlace执行reverseArray。您可以复制输入数组,将原来的副本反向并返回。 (您可以通过调用arr.slice()复制数组)

+0

这并不能解释为什么第三种方法有效。如果通过值传递的参数,全局对象将不会使用参数“myArray”进行修改。 – 2015-04-06 03:30:07

+0

参数是按值传递的。这并不意味着阵列被复制。这两个值仍然引用原始数组,所以'myArray [i]'修改数组的内容。 – dwickern 2015-04-06 03:50:04

1

里面的功能,myArray是指原数组变量,那么您对元素的任何改变,例如

myArray[i] = x; 

将改变原版的。但是,如果您将myArray变量设置为某个值,那么原始数组将被移出作用域,而您只将局部变量设置为反转数组。 @dwickern's answer为您提供修正代码的正确方法。