User 13204940 Ответов: 1

Установка значений в объектах JS


Я пытаюсь изменить значение в объекте для последующего использования. Почему значения не сохраняются с помощью этого метода?

У меня есть следующий код:
window.myobj = {
    a: {_a: '_a here', _b: '_b here', _c: ''},
    b: {_a: '_a here', _b: '_b here', _c: ''},
    c: {_a: '_a here', _b: '_b here', _c: ''}
    //etc.
}

myobj['a']._c = 'test';
alert(myobj['a']._c); // not test!
Это прекрасно работает для предопределенных значений, но не для динамически заданных.

РЕДАКТИРОВАТЬ:

Я сузил его до проблемы цикла - ключ всегда последний в массиве.
window.keys = Object.keys(servers);

for(var i = 0; i < keys.length; i++)
{
        var key = keys[i];
        var xhr = new XMLHttpRequest();

        xhr.addEventListener('load', function()
        {
                alert(key); // this is the issue due to this happening after the loop is finished
                myobj[key]._c = this.responseText;
        });

        xhr.open('GET', 'test.php?s=' + myobj[key]._b);
        xhr.send();
}


Что я уже пробовал:

Устанавливая значение непосредственно, используя ['_c'] и устанавливая myobj['a'] полностью на новый объект.

Thomas Daniels

Я попытался запустить это, и это предупредительный "тест", как и ожидалось и желалось.

User 13204940

Я отредактировал вопрос

1 Ответов

Рейтинг:
4

Thomas Daniels

Проблема "ключ всегда последний в массиве" действительно происходит потому, что события "загрузки" запускаются только после завершения цикла, так что key действительно равен последнему ключу в момент вашего вызова alert(key) Эта проблема может быть решена путем замены вашего addEventListener позвоните по этому телефону:

xhr.addEventListener('load', (function(k) {
  return function() {
    alert(k);

    myobj[k]._c = this.responseText;
  };
})(key));
Это выглядит немного сложно, поэтому давайте разберем этот фрагмент кода на его различные части.
(function(k) { ... })(key)
Вышесказанное является самоисполняющейся функцией. Когда функция выполняет себя, мы передаем key как то k параметр: k будет ли ключ в то время, что addEventListener мне позвонили и ... на него не повлияют изменения в системе key переменная.

Внутри самоисполняющейся функции мы возвращаем новую функцию. Нам нужно это сделать, потому что мы не хотим бежать alert (и другая строка) сразу же: мы хотим иметь функцию, которую мы можем передать addEventListener так что он работает на событии "load". Поэтому мы должны вернуть функцию, которую хотим запустить при событии "load":
return function() {
  alert(k);

  myobj[k]._c = this.responseText;
};
Мы используем k здесь и нет key, потому что мы хотим использовать переменную внутри самоисполняющейся функции, на которую не влияет key изменения.


User 13204940

Очень полезно. Я видел (что-то), используемое после функции(){} несколько раз, но я никогда не знал, что это делает. В итоге я использовал другое решение, передав ключ в php-файл и заставив его вернуть ключ вместе с результатом его обработки. Но все равно спасибо за помощь, это очень проницательно.

Thomas Daniels

Всегда пожалуйста!