IIFE ohtlikud kivid JavaScriptis
Vaatleme kaht koodijuppi.
Esimene:
let result = 1
+function() {
return 2;
}();
console.log(result);
Teine:
let result = 1;
+function() {
return 2;
}();
console.log(result);
Need kaks koodijuppi on peaaegu identsed,
kuid nende käivitamisel on tulemus erinev.
Esimene kood väljastab konsooli numbri 3,
ja teine - numbri 1.
Miks selline erinevus tekkis: kõik on selles, et ühel juhul on esimesel real koodi lõpus puudu semikoolon, ja teisel juhul - on olemas.
Võite küsida: kuidas nii, JavaScriptis ei ole ju semikoolon käsu lõpus kohustuslik! Tegelikult ei ole see päris nii. Mõtleme välja, mis meil tegelikult toimub.
Esimest koodi saab ümber kirjutada nii:
let result = 1 + function() {
return 2;
}();
console.log(result); // väljastab 3
Nüüd saab kohe selgeks, et
ühele liidetakse funktsiooni
kohese väljakutse tulemus,
see tähendab 2. Seetõttu on lõplik
tulemus 3.
Kui aga ühe järel panna semikoolon, tõlgendab interpretaator koodi teistmoodi:
// Esimene käsk:
let result = 1;
// Teine käsk:
+function() {
return 2;
}();
// Kolmas käsk:
console.log(result); // väljastab 1
See tähendab, et muutujasse omistamine ja funktsiooni kohene kutsumine saavad erinevateks käskudeks. Ja kõik semikooloni olemasolu tõttu!
Selgub, et antud juhul funktsiooni
kohene kutsumine
üldse midagi ei tee - lihtsalt
tühjusesse tagastab numbri 2, mis
ei mõjuta kuidagi muutujat result.
Mõtleme siis välja, miks me üldse võime mitte kirjutada semikoolonit JavaScriptis. Olgu meil selline kood ilma semikooloniteta:
let result = 1 // resulti kirjutatakse 1
let test = 2 // testi kirjutatakse 2
See töötab korrektselt, kuna interpretaator paneb ise igal rea lõpus semikooloni.
Kuid vaadake seda koodi:
let result = 1
+ 2; // resulti kirjutatakse 3
Nüüd esimese rea lõppu ei panda automaatselt semikoolonit, kuna interpretaator mõistab, et teise rea käsk - see on osa esimese rea käsust.
Kuid kui me ise paneme semikooloni - on tulemus hoopis teine:
let result = 1; // resulti kirjutatakse 1
+ 2; // käsk ei tee midagi, kuid viga ei teki
Selgub, et interpretaator paneb ise semikooloni ainult siis, kui järgmine käsk ei ole osa eelmisest.
Ja nüüd vaadake seda koodi:
let result = 1
+function() {
return 2;
}();
console.log(result);
Tõepoolest, teine rida - on lihtsalt jätk esimese rea käsule ja interpretaator ei panekki semikoolonit automaatselt. Just seetõttu, kui me ise kirjutame semikooloni esimese rea lõppu - on tulemus hoopis teine. See ütleb, et kõige parem on alati panna semikoolon vajalikku kohta, et vältida probleeme.