Падводныя камні 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

Гэта значыць прысвойванне ў зменную і выклік функцыі на месцы стануць рознымі камандамі. І ўсё з-за наяўнасці кропкі з коскай!

Атрымліваецца, што ў дадзеным выпадку выклік функцыі на месцы наогул нічога не робіць - проста ў нікуд вяртае лік 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);

Сапраўды, другая радок - проста працяг каманды першай радкі і інтэрпрэтатар не ставіць кропку з коскай аўтаматычна. Менавіта таму, калі мы самі напішам кропку з коскай у канцы першай радкі - вынік будзе зусім іншым. Гэта кажа пра тое, што лепш за ўсё заўсёды ставіць кропку з коскай у патрэбных месцах, каб пазбегнуць праблем.