Παγίδες των IIFE στην JavaScript
Ας εξετάσουμε δύο κομμάτια κώδικα.
Το πρώτο:
let result = 1
+function() {
return 2;
}();
console.log(result);
Το δεύτερο:
let result = 1;
+function() {
return 2;
}();
console.log(result);
Αυτά τα δύο κομμάτια κώδικα είναι σχεδόν πανομοιότυπα,
αλλά αν εκτελεστούν - το αποτέλεσμα θα διαφέρει.
Ο πρώτος κώδικας θα τυπώσει στην κονσόλα τον αριθμό 3,
ενώ ο δεύτερος - τον αριθμό 1.
Γιατί προέκυψε αυτή η διαφορά: όλα οφείλονται στο γεγονός ότι στη μια περίπτωση στην πρώτη γραμμή κώδικα στο τέλος απουσιάζει το ερωτηματικό, ενώ στη δεύτερη περίπτωση - υπάρχει.
Μπορείτε να ρωτήσετε: πώς γίνεται αυτό, αφού στην JavaScript το ερωτηματικό στο τέλος της εντολής δεν είναι υποχρεωτικό! Στην πραγματικότητα, αυτό δεν ισχύει ακριβώς. Ας δούμε τι πραγματικά συμβαίνει.
Ο πρώτος κώδικας μπορεί να ξαναγραφεί ως εξής:
let result = 1 + function() {
return 2;
}();
console.log(result); // θα τυπώσει 3
Τώρα γίνεται αμέσως προφανές ότι στο ένα
προστίθεται το αποτέλεσμα της κλήσης της συνάρτησης
αμέσως, δηλαδή 2. Επομένως, το τελικό
αποτέλεσμα θα είναι 3.
Εάν, ωστόσο, μετά το ένα τεθεί ερωτηματικό, ο κώδικας θα γίνει αντιληπτός από τον διερμηνευτή διαφορετικά:
// Πρώτη εντολή:
let result = 1;
// Δεύτερη εντολή:
+function() {
return 2;
}();
// Τρίτη εντολή:
console.log(result); // θα τυπώσει 1
Δηλαδή, η ανάθεση στη μεταβλητή και η κλήση της συνάρτησης αμέσως θα γίνουν διαφορετικές εντολές. Και όλα αυτά λόγω της παρουσίας του ερωτηματικού!
Αποδεικνύεται ότι σε αυτή την περίπτωση η κλήση της συνάρτησης
αμέσως δεν κάνει τίποτα - απλά
επιστρέφει τον αριθμό 2 πουθενά,
που δεν επηρεάζει με κανέναν τρόπο τη μεταβλητή result.
Ας δούμε, λοιπόν, γιατί μπορούμε γενικά να μην γράφουμε ερωτηματικό στην JavaScript. Ας υποθέσουμε ότι έχουμε έναν τέτοιο κώδικα χωρίς ερωτηματικά:
let result = 1 // στο result θα γραφτεί 1
let test = 2 // στο test θα γραφτεί 2
Λειτουργεί σωστά, καθώς ο διερμηνευτής έβαλε μόνος του στο τέλος κάθε γραμμής ερωτηματικό.
Αλλά δείτε αυτόν τον κώδικα:
let result = 1
+ 2; // στο result θα γραφτεί 3
Τώρα το ερωτηματικό στο τέλος της πρώτης γραμμής δεν θα τεθεί αυτόματα, καθώς ο διερμηνευτής καταλαβαίνει ότι η εντολή της δεύτερης γραμμής είναι μέρος της εντολής της πρώτης γραμμής.
Αλλά αν βάλουμε εμείς το ερωτηματικό - το αποτέλεσμα θα είναι εντελώς διαφορετικό:
let result = 1; // στο result θα γραφτεί 1
+ 2; // η εντολή δεν κάνει τίποτα, αλλά ούτε και θα προκύψει σφάλμα
Αποδεικνύεται ότι ο διερμηνευτής βάζει μόνος του ερωτηματικό, μόνο εάν η επόμενη εντολή δεν είναι μέρος της προηγούμενης.
Και τώρα δείτε αυτόν τον κώδικα:
let result = 1
+function() {
return 2;
}();
console.log(result);
Πράγματι, η δεύτερη γραμμή είναι απλά η συνέχεια της εντολής της πρώτης γραμμής και ο διερμηνευτής δεν βάζει ερωτηματικό αυτόματα. Αυτός ακριβώς είναι ο λόγος που, αν εμείς οι ίδιοι γράψουμε ερωτηματικό στο τέλος της πρώτης γραμμής - το αποτέλεσμα θα είναι εντελώς διαφορετικό. Αυτό μας λέει ότι είναι καλύτερα να βάζουμε πάντα ερωτηματικό στις απαραίτητες θέσεις, για να αποφεύγουμε προβλήματα.