@po4talben

Почему переменная не меняет значение, если обернуть действие в функцию?

В этом варианте переменная existence1 меняется на тру
let existence1 = existence2 = existence3 = existence4 = false;

productAdd.forEach((i, index) => i.addEventListener('click', (e) => {
  if (index === 0) {
    if (existence1) {console.log('+1')}
    else {
      console.log(existence1)
      existence1 = true;
    }
  }
}))


в этом варианте переменная existence1 не меняется и остается false
let existence1 = existence2 = existence3 = existence4 = false;

function addcartProduct (num) {
  if (num) {console.log('+1')}
    else {
      console.log(num)
      num = true;
    }
}

productAdd.forEach((i, index) => i.addEventListener('click', (e) => {
  if (index === 0) {
    addcartProduct(existence1)
  }
}))


Как сделать, чтобы переменная изменила значение? И объясните, пожалуйста, что происходит
  • Вопрос задан
  • 418 просмотров
Решения вопроса 1
neuotq
@neuotq
Прокрастинация
В первом случае происходят простое прямое изменение переменной existence1, вы там напрямую к ней обращаетесь и меняете значение.
Во втором случае в момент вызова addcartProduct(existence1) значение в переменной existence1 копируется и дальше используется внутри функции addcartProduct в переменной num. При передаче параметров переменные в javascript копируются по значению, те создаётся новая переменная и туда копируется значение из переденной в параметре(есть нюансы с объектами!). Во многих язык программирования есть инструменты позволяющие передавать переменную по ссылке, но javascript такого не поддерживает.
Поэтому будем использовать нюансы передачи значения в переменных объектах(и массивах).
Если огрубить, то при создании объекта в js сам объект создаётся где-то в памяти, а в переменную помещается идентификатор(ссылка) на то что это за объект. Так вот, при передаче объекта в функцию, в локальную переменную внутри копируется именно это значение(а не поля и элементы как кажется), поэтому переменная внутри функции хоть и другая, но ссылается на этот же объект в памяти.
Поэтому если мы изменим свойства этого объекта, то они поменяются и в оригинале. При это если бы эту локальную переменную перепишем(например создадим новый объект) то внешняя переменная не изменится, ведь во внешней осталась оригинальная ссылка на старый объект, а во внутреннем будет новая уже.
Кажется непонятным, но все просто если понять что у объектов(и массивов) значение переменной это айди объекта в памяти, а переменные в js передаются всегда по значению, поэтому всё логично.
Итак перепишем ваш пример, чтобы мы могли менять значение снаружи из функции через локальную переменную.

//Объекты обычно объявляют как константы, чтобы случайно не переписать сам объект
//при это свойства объекта менять можно
//потому что константа это значение переменной - ссылка на объект в памяти
const existence1=  { 
value: false
};

function addcartProduct (num) {
  if (num.value) {console.log('+1')}
    else {
      console.log(num)
      num.value = true;
    }
}

//false
console.log(existence1.value)

addcartProduct(existence1);
//true
console.log(existence1.value)
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы