Я столкнулся с интересной проблемой, работая с составными операторами присваивания в JavaScript. При использовании нескольких операторов одновременно выходит неожиданный результат.
Пример кода
let number = 5;
number += number -= number * number;
console.log(number); // показывается -15
Сравнение с другими языками
В C++ тот же код дает другой результат:
int number = 5;
number += number -= number * number;
// результат: number = -40
Вопрос
Почему в JavaScript результат отличается от C++? Как JavaScript обрабатывает такие вложенные операции присваивания? Есть ли особенности в порядке выполнения этих операторов в JS?
Буду признателен за объяснение механизма работы и причины такого значения.
Забавная штука с порядком вычислений! JS движок сначала определяет все ссылки на переменные, потом выполняет операции. Для += он уже ‘заморозил’ значение 5, даже если справа переменная поменялась. А в С++ компилятор переставляет операции как хочет. Кстати, специально такой код писал или случайно наткнулся?
JS вычисляет операнды в определенном порядке. Движок видит number += number -= number * number и сразу запоминает левый операнд для += (это 5), а потом уже считает правую часть. Сначала выполняется number -= number * number, получается -20, потом делается 5 + (-20). Это undefined behavior - в разных языках работает по-разному. В продакшене такое лучше не писать.
дело в том, что js и c++ по-разному обрабатывают эти выражения. в джаваскрипте += сначала запоминает исходное значение левой части, а потом вычисляет правую. то есть number += (правая часть) берет изначальное значение 5, а не то что меняется по ходу вычислений справа. поэтому получается 5 + (-20) = -15. в c++ алгоритм другой - переменная обновляется сразу. это особенность js, которая может удивить. лучше не писать такие запутанные конструкции - код должен быть понятным