@Sergey-Nag

Почему при присвоении значения переменной «1» переменной «2», переменная «2» заменяется на «1»?

Доброго времени суток, в общем, я самоучка, делаю телеграм-бота на Node.JS.
Реализую возможность оформления заказа, но в процессе появилась проблема, которую не пойму как решить.
Нужно присвоить переменной «1» значение переменной «2». В итоге получается, что ничего не меняется, а значение переменной «2» меняется на переменную «1», то есть все происходит наоборот.
Я не знаю, как это понятно объяснить, так что вот как я делал:
Есть объект с «сессиями», при отправлении пользователем сообщения, происходит следующее:
session[ID] = session[ID] || {
    log: [PathTmpl.main_menu],
    inline_log: '',
    name: ctx.from.first_name,
    last_name: ctx.from.last_name,
    auth: 'new',
    admin: false,
    orders: [],
    phone: '',
    delivery: emptyAdress,
    order: emptyOrder
  }

Стоит обратить внимание на переменные order и orders.

Объект emptyOrder является константой, с ключами и пустыми значениями
const emptyOrder = {
  id: 0,
  name: '',
  pack: '',
  code: '',
  amount: '',
  price: ''
}


Orders является массивом, в него добавляются выбранные товары из объекта order.
По мере выбора товара, в order добавляются данные:
session[ID].order.code = code
…
session[ID].order.name = infoTxt.name
…
session[ID].order.pack = infoTxt.packing
…
session[ID].order.price = infoTxt.cost
…
session[ID].order.amount= amountNum


После этого order пушиться в массив orders и очищается с сохранением ключей:
session[id].orders.push(session[id].order)
session[id].order = emptyOrder

Вроде все логично, но стоит посмотреть, что находится в переменных СРАЗУ после этих строк
Вывожу в консоль
console.log('\n session[id].orders : \n', session[id].orders) // массив
console.log('\n session[id].order : \n', session[id].order) // объект
console.log('\n emptyOrder : \n', emptyOrder) // константа

5bfbcfb518a5c896625501.png
Уже можно заметить, что переменная emptyOrder заменилась на значение order, но такого не должно происходить. А сама order не очистилась…
А вот что произойдет, если добавить еще один товар:
5bfbd032cc586958747731.png
То есть оно не добавляет новы товар в массив, а заменяет все элементы на последний выбранный товар.
5bfbd08173c77765364782.png
Не пойму с чем это связано и как это решить.
Такая же ситуация с информацией о доставке. Заметил что после того, как один пользователь ввел адрес доставки, он добавляется в константу emptyAdress, и после этого следующему пользователю выводится информация с этого же emptyAdress, то есть он видит данные другого пользователя!

Интересно, кто сталкивался с подобным, какие есть варианты решения?)
  • Вопрос задан
  • 223 просмотра
Решения вопроса 1
dollar
@dollar
Делай добро и бросай его в воду.
Вы присваиваете не значение, а ссылку на значение. Так происходит с объектами и массивами.

let a = {x:1};
let b = a; // Теперь a и b указывают на один и тот же участок памяти.
b.x = 2;
console.log(a.x); // 2    Ах, вот оно как!

//Как скопировать:
let c = {}; //Создается новый объект и под него выделяется новая память
c.x = a.x; //Копирование значений, т.к. x это не объект.

//Универсальный вариант (копируются все свойства):
a.y = 11;
a.z = 111;
let d = Object.assign({}, a); 
console.log(d); // {x:1, y:11, z:111}

Object.assign()
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
PretorDH
@PretorDH
HTML5, CSS3, PHP, JS - люблю в чистом виде.
Когда вы присваиваете объект, вы присваиваете ссылку на объект, а не делаете его копию. А потом переписываете поля самого emptyOrder, через ссылку на emptyOrder в session[ID].order. Нужно делать копию данных...

session[ID] = session[ID] || {
log: [PathTmpl.main_menu],
inline_log: '',
name: ctx.from.first_name,
last_name: ctx.from.last_name,
auth: 'new',
admin: false,
orders: [],
phone: '',
delivery: emptyAdress,
order: Object.assign({}, emptyOrder)
}

P.S. Не забудьте подключить полифил для Object.assign или пользуйтесь аналогичным методом фреймворка.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы