(ПРОПУЩЕНО: https://javascriptlearner815.github.io/2021/04/22/using-the-internet-without-power.html)

ЗАПИСЬ В БЛОГЕ: https://javascriptlearner815.github.io/2021/04/23/javascript-plus-plus-vs-plus-plus-javascript-solved.html

(JavaScript++ && ++JavaScript) && console.log('Solved')

Вот вам код JavaScript:

function f(x) {
  x++
  (x = x - 3) && ++x
  return x--
}
f(2) // 0

Думаете, код работает так?

function f(x) { // 2
  x++ // 3
  (x = x - 3) /* 0 */ && ++x // 1
  return x-- // 0
}
f(2) // 0

Правильно? НЕПРАВИЛЬНЫЙ!

Код на самом деле работает так:

function f(x) { // 2
  x++ // 3
  (x = x - 3) /* 0 */ && ++x // 0
  return x-- // 0, but x is now actually -1
}
f(2) // 0

В этой статье я покажу вам, почему это происходит, и различия между x++ и ++x. (Это очень важная тема в JavaScript, так что слушайте!)

(Этот код был создан WebDevSimplified для Who Wants To Be A Megabit.)

Определения

x++

Использование x++ возвращает текущее значение x и затем увеличивает его на 1.

++x

Использование ++x увеличивает его на 1, а затем возвращает новое значение x.

Примеры

Давайте немного отойдем от этого большого примера.

Я имею в виду, много.

Допустим, вы создавали функцию, которая увеличивает x и устанавливает y на одно и то же значение.

Давайте попробуем сделать это с помощью x++:

let x = 360
let y
function incrementXAndSetToY(x, y) {
  y = x++
}
incrementXAndSetToY(x, y)

Теперь вы ожидаете, что x будет 361, а y тоже будет 361, верно?

НЕПРАВИЛЬНЫЙ!

Если вы попытаетесь вывести эти переменные в консоль, вы получите такой результат:

console.log(x) // 361
console.log(y) // 360

Это связано с тем, что по определению x++ возвращает значение x до увеличения, которое в данном случае является начальным объявлением, 360, а затем мы устанавливаем y равным этому.

Теперь мы могли бы написать функцию следующим образом:

let x = 360
let y
function incrementXAndSetToY(x, y) {
  x++
  y = x
}
incrementXAndSetToY(x, y) // Now both x and y are set to 361

…Но есть лучший способ, лучшая практика.

Просто используйте ++x:

let x = 360
let y
function incrementXAndSetToY(x, y) {
  y = ++x
}
incrementXAndSetToY(x, y) // Now both x and y are set to 361

Теперь, просто изменив положение ++ относительно x, мы сузили этот код почти до того же, что и в начале, только он помещается в одну строку и выглядит лучше для разработчиков среднего уровня.

Вернемся к Большому Бою

С нашими новыми знаниями давайте разберем «большой код BOI» шаг за шагом:

function f(x) { // 3
  x++ // 3 /*<
^^^^^^^^^^^^^^*/
  (x = x - 3) /* 0 */ && ++x // 0
  return x-- // 0, but x is now actually -1
}
f(2) // 0

Это увеличивает x на 1, поэтому со значением, которое мы передали, 2, x теперь равно 3.

function f(x) { // 3
  x++ // 3
  (x = x - 3) /* 0 */ && ++x // 0 /*<
^^^^^^^^^^^^^^*/
  return x-- // 0, but x is now actually -1
}
f(2) // 0

Это делает ДВЕ вещи.

Во-первых, мы устанавливаем x в его текущее значение, 3 минус 3, что равно 0.

Во-вторых, после этого мы добавляем && и увеличиваем x на ++x. Это установит x на 1 сейчас, однако, когда мы установим x на 0, это присвоение вернет новое значение x, 0, которое является ложным значением. Таким образом, && замыкается и не запускается. (Возможно, я скоро напишу об этом еще одну статью, возможно, завтра.)

Итак, значение x теперь равно 0.

function f(x) { // 3
  x++ // 3
  (x = x - 3) /* 0 */ && ++x // 0
  return x-- // 0, but x is now actually -1 /*<
^^^^^^^^^^^^^^*/
}
f(2) // 0

Это запрашивает выполнение оператора return и DECREMENTS x с x--.

Однако по определению return возвращается из функции и делает свое значение равным значению выражения после оператора return, или undefined, если его нет или есть перевод строки (из-за ASI, опять же, может тоже написать отдельную статью об этом скоро). Помните, что x-- возвращает значение x до уменьшения. Таким образом, оператор return выходит из функции со значением 0. Затем строка f(2) просто запускает функции с нашим уже учтенным значением 2, которое возвращает значение 0.

(ПРИМЕЧАНИЕ: если бы значение x могло появиться, оно было бы правильно равно -1, очевидно, из-за приведенного выше определения.)

Вывод

x++ vs. ++x — это очень распространенная тема, которая затрагивается практически везде, но она имеет решающее значение для начинающих, которые застревают, пытаясь изучить код разработчиков среднего уровня, содержащий такие удивительные, жизненно важные знания. Если вы когда-нибудь попытаетесь подать заявку на вакансию разработчика в JavaScript и не будете знать разницу между x++ и ++x, это сразу станет для них сигналом опасности, поскольку это очень простое и необходимое знание, которое нужно указать в вашем резюме.

Спасибо за чтение (и ведение блога с помощью GitHub Pages и др.) и хорошего дня!