Подводные камни IIFE в JavaScript

Давайте рассмотрим два кусочка кода.

Первый:

javascriptlet result = 1
+function() {
  return 2;
}();

console.log(result);

Второй:

javascriptlet result = 1;
+function() {
  return 2;
}();

console.log(result);

Эти два кусочка кода практически одинаковы, но если их запустить - результат будет отличаться. Первый код выведет в консоль число 3, а второй - число 1.

Почему получилась такая разница: все дело в том, что в одном случае в первой строке кода в конце отсутствует точка с запятой, а во втором случае - присутствует.

Вы можете спросить: как же так, ведь в JavaScript точка с запятой в конце команды не является обязательной! На самом деле это не совсем так. Давайте разберемся, что у нас на самом деле происходит.

Первый код можно переписать вот так:

javascriptlet result = 1 + function() {
  return 2;
}();

console.log(result); // выведет 3

Теперь сразу становится очевидным, что к единице прибавляется результат вызова функции на месте, то есть 2. Поэтому итоговый результат будет 3.

Если же после единицы поставить точку с запятой, то код будет воспринят интерпретатором по-другому:

javascript// Первая команда:
let result = 1;

// Вторая команда:
+function() {
  return 2;
}();

// Третья команда:
console.log(result); // выведет 1

To есть присваивание в переменную и вызов функции на месте станут разными командами. И все из-за наличия точки с запятой!

Получается, что в данном случае вызов функции на месте вообще ничего не делает - просто вникуда возвращает число 2, которое никак не влияет на переменную result.

Давайте тогда разберемся, а почему мы вообще можем не писать точку с запятой в JavaScript. Пусть у нас есть такой код без точек с запятыми:

javascriptlet result = 1 // в result запишется 1
let test = 2   // в test запишется 2

Он работает корректно, так как интерпретатор сам расставил в конце каждой строки точку с запятой.

Но посмотрите на такой код:

javascriptlet result = 1
+ 2; // в result запишется 3

Теперь точка с запятой в конце первой строки не поставится автоматически, так как интерпретатор понимает, что команда второй строки - это часть команды первой строки.

Но если мы сами поставим точку с запятой - результат будет совсем другим:

javascriptlet result = 1; // в result запишется 1
+ 2; // команда ничего не делает, но и ошибки не будет

Получается, что интерпретатор сам ставит точку с запятой, только если следующая команда не является частью предыдущей.

А теперь посмотрите на этот код:

javascriptlet result = 1
+function() {
  return 2;
}();

console.log(result);

Действительно, вторая строка - просто продолжение команды первой строки и интерпретатор не ставит точку с запятой автоматически. Именно поэтому, если мы сами напишем точку с запятой в конце первой строки - результат будет совсем другим. Это говорит о том, что лучше всего всегда ставить точку с запятой в нужных местах, во избежание проблем.