IIFE:n sudenkuopat JavaScriptissä

Tarkastellaan kahta koodinpätkää.

Ensimmäinen:

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

console.log(result);

Toinen:

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

console.log(result);

Nämä kaksi koodinpätkää ovat lähes identtisiä, mutta jos ne suoritetaan - tulos on erilainen. Ensimmäinen koodi tulostaa konsoliin numeron 3, kun taas toinen - numeron 1.

Miksi tällaista eroa syntyy: kyse on siitä, että yhdessä tapauksessa ensimmäisen rivin lopussa ei ole puolipistettä, kun taas toisessa tapauksessa - on.

Saattaa kysyä: kuinka niin, eihän JavaScriptissä puolipiste komennon lopussa ole pakollinen! Itse asiassa näin ei ole aivan tottta. Selvitetään, mitä todella tapahtuu.

Ensimmäinen koodi voidaan kirjoittaa uudelleen näin:

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

console.log(result); // tulostaa 3

Nyt käy heti selväksi, että ykköseen lisätään funktion paikan päällä kutsunnan tulos eli 2. Siksi lopullinen tulos on 3.

Jos ykkösen jälkeen laitetaan puolipiste, koodi tulkitaan tulkin eri tavalla:

javascript// Ensimmäinen komento:
let result = 1;

// Toinen komento:
+function() {
  return 2;
}();

// Kolmas komento:
console.log(result); // tulostaa 1

Eli muuttujaan sijoitus ja funktion paikan päällä kutsuminen tulevat eri komennoiksi. Ja kaikki puolipisteen takia!

Osoittautuu, että tässä tapauksessa funktion paikan päällä kutsuminen ei yleensä tee mitään - yksinkertaisesti tyhjään palauttaa numeron 2, joka ei vaikuta muuttujaan result millään tavalla.

Selvitetään sitten, miksi voimme yleensä olla kirjoittamatta puolipistettä JavaScriptissä. Olkoon meillä tällainen koodi ilman puolipisteitä:

javascriptlet result = 1 // resultiin kirjoitetaan 1
let test = 2   // testiin kirjoitetaan 2

Se toimii oikein, koska tulkkia asioi itse kunkin rivin lopussa puolipisteen.

Mutta katsokaa tällaista koodia:

javascriptlet result = 1
+ 2; // resultiin kirjoitetaan 3

Nyt puolipistettä ensimmäisen rivin lopussa ei aseteta automaattisesti, koska tulkkia ymmärtää, että toisen rivin komento on osa ensimmäisen rivin komentoa.

Mutta jos asetamme itse puolipisteen - tulos on aivan toinen:

javascriptlet result = 1; // resultiin kirjoitetaan 1
+ 2; // komento ei tee mitään, mutta virhettäkään ei tule

Osoittautuu, että tulkkia asettaa itse puolipisteen, vain jos seuraava komento ei ole osa edellistä.

Ja katsokaa tätä koodia:

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

console.log(result);

Todellakin, toinen rivi on yksinkertaisesti jatkoa ensimmäisen rivin komennolle ja tulkkia ei aseta puolipistettä automaattisesti. Juuri siksi, jos kirjoitamme itse pisteen ensimmäisen rivin lopussa - tulos on aivan toinen. Tämä kertoo, että on parasta aina asettaa puolipiste tarvittaviin paikkoihin, ongelmien välttämiseksi.