Сначала я добавляю две одинаковые строки в массив, а позже мне нужно изменить только последнюю, добавив к ней новое свойство. Как я это делаю:
for(var index in arrayOne) {
var arrayOneItem = arrayOne[index];
var new_row = {
address: arrayOne[index].address,
date: arrayOne[index].date,
category: arrayOne[index].category,
};
rows.push(new_row);
if (arrayOne[index].refund_status == 'refunded') {
rows.push(new_row);
rows[rows.length - 1].refund_status = 'refunded';
}
}
Но проблема в том, что код внутри оператора if изменяет не только последнюю строку, но и предыдущую, поэтому refund_status = 'refunded' добавляется и к последней, и к предпоследней строке. Почему это происходит и есть ли способ изменить только последнюю строку?
@Ele Понятно, что мне использовать вместо этого?
Пожалуйста, укажите значение arrayOne



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Это связано с тем, что объект, который вы вставляете в массив, передается по ссылке, а не по значению, поэтому при изменении исходного объекта вы измените обе ссылки на него в массиве, см. пример ниже:
let someArray = [];
let someObj = {foo: "bar"};
someArray.push(someObj);
someArray.push(someObj);
someArray[0].foo = "baz";
console.info(someArray[1]);Чтобы избежать этого, вам нужно будет клонировать значения объекта, чтобы создать новый. В вопросе Этот есть несколько способов сделать это, используя JSON.parse и JSON.stringify, это самый короткий способ глубоко скопировать объект без внешней библиотеки, см. пример ниже:
let someArray = [];
let someObj = {foo: "bar"};
someArray.push(someObj);
let newObj = JSON.parse(JSON.stringify(someObj));
someArray.push(newObj);
someArray[0].foo = "baz";
console.info(someArray[1]);Когда вы используете один и тот же объект дважды, лучше всего создать копию (в данном случае неглубокую) с помощью Object.assign(). Это позволит избежать ссылки на один и тот же объект из нескольких переменных или индексов массива в вашем случае.
например.
rows.push(new_row);
становится
rows.push(Object.assign({}, new_row));
Другие решения тоже работают, но это было самым быстрым, а также не сложным
Потому что вы меняете свойство object, а доступ к object в javaScript осуществляется через ссылку, а не через отдельный экземпляр. Другими словами, у вас есть один и тот же объект в памяти, и вы меняете его свойство. Это означает, что new_row — это объект, который вы создаете и нажимаете несколько раз, и это одно и то же.
Вы можете избежать этого, скопировав его при нажатии во второй раз:
if (arrayOne[index].refund_status == 'refunded') {
rows.push({ ...new_row });
rows[rows.length - 1].refund_status = 'refunded';
}
где { ...new_row } в основном создает новую копию.
Когда вы это сделаете rows[rows.length - 1].refund_status = 'refunded';, изменится только предпоследнее.
Другое решение, которое я бы предложил, немного точнее:
const rows = []; // empty
const arrayOne = []; // SOME DATA HERE as I understand
const refundedStatus = ;
arrayOne.forEach(element=> {
rows.push(element);
if (value.refund_status === 'refunded') {
rows[rows.length].refund_status = 'refunded';
rows.push({ ...element});
}
});
inдля итерации, иногда массив, являющийся объектом, может содержать дополнительные свойства, не являющиеся индексами. Вместо этого используйте операторfor...of.