JavaScript не может установить текущую ситуацию измененного объекта для массива в цикле for - PullRequest
0 голосов
/ 21 ноября 2018

Когда я запускаю этот код, все объекты массива совпадают.

var obj = {
    	a: { b: 0 }
    }

    var arr = [];

    for(i = 0; i < 10; i++) {
    arr.push(obj);
    obj.a.b += 5;
    }

    for(i = 0; i < arr.length; i++) {
    document.writeln(arr[i].a.b);
    }

Как отправить текущие значения объекта в массив?Как:

[
  {"a": b: 5 },
  {"a": b: 10 },
  {"a": b: 15 },
...
]

jsfiddle

enter image description here


После ответа

Я создал эталонный тест для Object.assign против JSON.stringify для глубокого клона.

http://jsben.ch/64Cxe

Ответы [ 3 ]

0 голосов
/ 21 ноября 2018

Это связано со значением в сравнении со ссылкой.

Stackoverflow превращает значение объекта в строку перед регистрацией.Когда вы затем изменяете значение объекта, строка не изменяется.

Журналы Chrome делают это немного по-другому, они регистрируют фактическое значение объекта, просматривая определенную точку в памяти, когда вызатем отредактируйте этот объект, журнал также обновится, потому что он по-прежнему указывает на эту часть памяти.

Если вы хотите также превратить его в строку, вы можете использовать JSON.stringify(obj);

0 голосов
/ 21 ноября 2018

obj - это ссылка на объект, поэтому вы действительно снова и снова толкаете одну и ту же ссылку на объект.

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

arr.push({...obj})

или

arr.push(Object.assign({},obj})

0 голосов
/ 21 ноября 2018

Консоль Chrome не отображает полный объект для console.log(obj);, а только { a: {...} } - и когда вы нажимаете «треугольник», чтобы отобразить содержимое объекта, консоль Chrome использует фактическое значение объекта.

Отрезанный StackOverflow отображает полное содержимое объекта сразу на каждой итерации - но Chrome только сохраняет ссылку на объект и смотрит на него глубже, только когда пользователь нажимает на «треугольник» в консоли.

Вы должны сделать вложенным(глубокое) копирование (популярным способом является, например, JSON.parse(JSON.stringify(obj)), но вы можете найти лучших способов для StackOverflow ) объекта на текущей итерации цикла и передать эту глубокую копию console.log (copyObj);,Например:

var obj = {
  a: {
    b: 0
  }
}

for (i = 0; i < 10; i++) {
  obj.a.b += 5;
  console.log('log obj.a.b = ' + obj.a.b);
  console.log( JSON.parse(JSON.stringify(obj)) );
}

После обновления вопроса

arr.push(obj) выдвигать в массиве только ссылку на тот же объект obj, используйте приведенный ниже код для добавления отдельной копии obj (точнее ссылка на копию) как новый элемент массива:

arr.push( JSON.parse(JSON.stringify(obj)) )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...