Область действия аргумента и изменчивость объекта в 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);

person Sergio Rodriguez    schedule 06.04.2015    source источник
comment
См. это для объяснения того, почему не работают части не работают: /13508654#13508654" title="почему значения объектов фиксируются внутри вызовов функций"> stackoverflow.com/questions/13506398/   -  person slebetman    schedule 06.04.2015


Ответы (2)


Ваши reverseArrayInPlace1 и reverseArrayInPlace2 не работают, потому что в JavaScript аргументы передаются по значению. myArray является локальным для функции, и его переназначение не влияет на вызывающую программу.

Вы можете применить противоположный подход к повторному использованию кода и реализовать reverseArray с точки зрения reverseArrayInPlace. Вы бы скопировали входной массив, перевернули копию на место и вернули ее. (Вы можете скопировать массив, вызвав arr.slice())

person dwickern    schedule 06.04.2015
comment
Это не объясняет, почему работает третий подход. Если аргументы передаются по значению, глобальный объект не будет изменен с использованием аргумента myArray. - person Sergio Rodriguez; 06.04.2015
comment
Аргумент передается по значению. Это не означает, что массив копируется. Оба значения по-прежнему ссылаются на исходный массив, поэтому myArray[i] изменяет содержимое массива. - person dwickern; 06.04.2015

Внутри вашей функции myArray — это переменная, которая ссылается на исходный массив, поэтому любые изменения, которые вы вносите в элементы, например

myArray[i] = x;

изменит оригинал. Но если вы присвоите myArray переменной какое-то значение, то исходный массив будет выведен за пределы области видимости, и вы только установите локальную переменную в перевернутый массив. ответ @dwickern дает вам правильную идею для исправления вашего кода.

person rvighne    schedule 06.04.2015