Цикл JavaScript меняет исходный массив данных, а также результат - как получилось? - PullRequest
0 голосов
/ 21 марта 2011

Я полностью сбит с толку. У меня есть объект, содержащий глобальный «хэшированный» массив чисел (в objectA), который упоминается в цикле, который объединяет числа в новую серию (в objectB).

var objectB = objectA[arrActive[0]]; 
for (i=1; i<arrActive.length; i++) {    
    var _this = arrActive[i];
    for (x=0; x<objectB.length; x++) {  
    objectB[x][1] += objectA[_this][x][1];  
    }
}

Что странно в том, что значения в objectA, исходном массиве, увеличиваются во время цикла - но почему? Насколько я знаю, я просто читаю из objectA для записи в objectB!

Это расстраивает, потому что каждый раз, когда вызывается функция, цифры снова завышаются!

Рабочий пример для JSFiddle приведен здесь: http://jsfiddle.net/ZbWGH/ - полностью ли я неправильно понял оператор + =? Я уверен, что это простая проблема, чтобы понять.

Заранее спасибо за любую помощь!

Ответы [ 3 ]

2 голосов
/ 21 марта 2011

Вы помещаете ссылку на экземпляр objectA['ONE'] в переменную с именем objectB - любое изменение в этой переменной действительно изменит фактическое значение.

Вместо этого вас может заинтересовать получение клона или "чистой копии" массива в objectB, и таким образом он не изменит исходный массив.

Простая функция, которая сделает это:

function CopyArray(arr) {
    var clone = [];
    for (var i = 0; i < arr.length; i++) {
        var subArray = [];
        for (var j = 0; j < arr[i].length; j++)
            subArray.push(arr[i][j]);
        clone.push(subArray);
    }
    return clone;
}

И использовать его:

var objectB = CopyArray(objectA[arrActive[0]]); 

Обновлен jsFiddle: http://jsfiddle.net/yahavbr/ZbWGH/1/

0 голосов
/ 21 марта 2011

Знаете ли вы C?Ссылки / указатели на C - хороший способ понять сложные переменные в Javascript.«Комплекс» означает все, что не является числом, строкой, логическим значением - все остальное является «объектом».Переменные для комплексных типов (объектов) действительно похожи на указатели.Если вам известны понятия «вызов по ссылке» и «вызов по значению», в Javascript это не так, вроде: если вы передаете объекты функциям, сам «указатель» является вызовом по значению, но значение является ссылкой наобъект (на самом деле в область в куче, где хранится объект, хотя JS-программисты не обрабатывают кучу, как в C / C ++, это все еще место хранения вещей).Пример:

function fn (a) {
  //changing the argument itself does NOT change the original object
  a = null;
  //but changing its properties does:
  a.foo = 42;
}

var o = { foo:1, bar:2 };

fn(o);

Так что теперь должно стать понятно, почему вы должны клонировать объект, если вы хотите настоящий «вызов по значению».Эта реализация была выбрана для JS, потому что в противном случае каждый раз, когда вызывается функция с не примитивным типом, куча должна быть скопирована, и 99% времени просто не требуется.«Истинный» дух функционального программирования, конечно, был бы чисто вызовом по значению, здесь мы видим практические соображения (производительность и использование памяти), которые нарушают теорию:)

0 голосов
/ 21 марта 2011

Далее больше A += B похоже на A = A + B, поэтому вы изменяете объект A.

...