Οι μεταβλητές που δηλώνονται με το var keyword έχουν το scope της function που δηλώθηκαν.
Πάμε να δούμε μερικά παραδείγματα.
var foo = "bar";
if (true) {
var foo = "baz";
console.log(foo); // prints baz
}
console.log(foo); // prints bazTι συμβαίνει στο παραπάνω κομμάτι κώδικα; Δηλώνουμε μια μεταβλητή foo με τιμή bar. Στη συνέχεια, έχουμε μια if και μέσα της δηλώνουμε ξανά τη μεταβλητή foo, αλλά αυτή τη φορά με την τιμή baz. Τέλος, κάνουμε print μέσα και έξω από την if τη μεταβλητή foo και βλέπουμε πως έχει την τιμή baz.
Αυτό συμβαίνει διότι δεν υπάρχει κάποια function και οι 2 μεταβλητές ανήκουν στο global scope. Οι μεταβλητές που δηλώνουμε με το keyword var δεν ανήκουν στο block scope που δηλώθηκαν αν αυτό δεν ανήκει σε function.
Πάμε να δούμε πως θα άλλαζε αυτό αν χρησιμοποιούσαμε μια function.
var foo = "bar";
function scope() {
var foo = "baz";
console.log(foo); // prints baz
}
console.log(foo); // prints barΕδώ βλέπουμε πως την πρώτη φορά το foo που θα εκτυπωθεί μέσα από την function scope θα είναι baz, ενώ μετά θα εκτυπωθεί bar.
Στις νέες εκδόσεις της JavaScript έχουμε 2 επιπλέον τρόπους για να δηλώνουμε μεταβλητές. Ας δούμε πως θα έτρεχαν τα προηγούμενα παραδείγματα χρησιμοποιώντας το let keyword.
let foo = "bar";
if (true) {
let foo = "baz";
console.log(foo); // prints baz
}
console.log(foo); // prints barΒλέπουμε πως δηλώνοντας τη μεταβλητή foo με το let keyword ανήκει στο block scope της if και δεν κάνει override την τιμή της πρώτης μεταβλητής foo.
Ένα κλασικό JavaScript quiz για μεταβλητές είναι το παρακάτω:
for (var index = 0; index < 3; index++) {
setTimeout(function() {
console.log(index);
}, 300);
}
// Output
3
3
3Μερικοί τρόποι για να το διορθώσουμε είναι οι παρακάτω:
Στην πρώτη περίπτωση χρησιμοποιούμε μια IIFE (μια function που καλεί τον εαυτό της αμέσως - Immediately Invoked Function Expression) για να περάσουμε το index στην function και πλέον να έχει δικό της scope και όχι το global.
for (var index = 0; index < 3; index++) {
(function(index) {
setTimeout(function() {
console.log(index);
}, 500);
})(index);
}
// Output
0
1
2Χρησιμοποιώντας το let keyword, το index έχει block scope και είναι διαφορετικό σε κάθε επανάληψη.
for (let index = 0; index < 3; index++) {
setTimeout(function() {
console.log(index);
}, 300);
}
// Output
0
1
2Ο δεύτερος τρόπος για να δηλώσουμε 'μεταβλητές' είναι με το keyword const. Δεν είναι τόσο μεταβλητές βέβαια όσο σταθερές.
const name = "SocialNerds";Αν τώρα προσπαθήσουμε να αλλάξουμε την τιμή της σταθεράς name, θα εμφανιστεί το παρακάτω exception:
Uncaught TypeError: Assignment to constant variable.
Στην περίπτωση που η τιμή της σταθεράς είναι object, μπορούμε να κάνουμε το παρακάτω:
const obj = { name: "SocialNerds" };
console.log(obj.name); // SocialNerds;
obj.name = "Thanos";
console.log(obj.name); // Thanos;Αλλά δεν μπορούμε να κάνουμε,
obj = { name: "Giannis" };Γιατί εμφανίζει,
Uncaught TypeError: Assignment to constant variable.
Στην περίπτωση που η τιμή της σταθεράς είναι array, μπορούμε να κάνουμε το παρακάτω:
const arr = [1, 2, 3];
arr.push(4);
console.log(arr) // 1, 2, 3, 4Αλλά δεν μπορούμε να κάνουμε,
arr = [];Γιατί εμφανίζει,
Uncaught TypeError: Assignment to constant variable.
Τα template literals είναι ένας νέος τρόπος για να γράφουμε strings. Ως τώρα μπορούσαμε να δηλώσουμε ένα string χρησιμοποιώντας single και double quotes (", ') . Πλέον έχουμε τη δυνατότητα να το κάνουμε χρησιμοποιώντας back-ticks (`).
Αρχικά, μπορούμε να φτιάξουμε ένα string πολλών γραμμών χωρίς να χρειάζεται να κάνουμε κάτι ιδιαίτερο.
let paragraph = `
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
when an unknown printer took a galley of type and scrambled it to make a type specimen book.
`;Διαφορετικά έπρεπε να δηλώσουμε εμείς την αλλαγή γραμμής με \n.
let paragraph = "
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's \n
standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a \n type specimen book.
";Επίσης, μπορούμε να χρησιμοποιήσουμε μεταβλητές μέσα στo string με ${}.
const name = "Thanos";
const message = `Hello, ${name}`;
console.log(message) // prints Hello, ThanosΑλλά να καλέσουμε ακόμα και functions.
function getColor(position) {
return position > 10 ? "red" : "blue";
}
const color = `btn btn-${getColor(30)}`;
console.log(color); // btn btn-redΗ arrow function είναι μια νέα σύνταξη της JavaScript για να γράφουμε function expressions. Πέρα από τη διαφορετική σύνταξη, έχει ακόμα μια σημαντική διαφορά που είναι ότι δεν δημιουργεί δικό της context, δηλαδή this.
Ας δούμε για αρχή, πως μπορούμε να συντάξουμε μια arrow function.
Η σύνταξη της είναι πολύ απλή καθώς δεν χρειάζεται να γράψουμε καμία λέξη: () => {}. Ξεκινάει με παρενθέσεις που μέσα δηλώνουμε τις παραμέτρους της function (param1, param2), στη συνέχεια, ένα fat arrow => και τέλος αγκύλες που μέσα υπάρχει ο κώδικας της function μας.
Πάμε να δούμε πως μπορούμε να φτιάξουμε μια function που προσθέτει 2 αριθμούς χρησιμοποιώντας μια arrow function.
Aναθέτουμε τη συνάρτησή μας σε μια μεταβλητή για να μπορέσουμε να την καλέσουμε αργότερα.
const add = (a, b) => {
return a + b;
};
console.log(add(1, 2)); // 3;Εκτός από αυτή τη σύνταξη όμως, μπορούμε να μειώσουμε και άλλο τον κώδικα μας χρησιμοποιώντας μερικές παραλλαγές στη σύνταξη της arrow function.
Όταν η function μας είναι μια γραμμή, όπως η add που είδαμε πιο πάνω, μπορούμε να επιστρέψουμε αμέσως το αποτέλεσμα χωρίς να χρησιμοποιήσουμε το return και τις αγκύλες. Αυτό ονομάζεται implicit return.
const add = (a, b) => a + b ή const add = (a, b) => (a + b);
Στη συγκεκριμένη περίπτωση επιστρέφουμε αμέσως το άθροισμα του a + b.
Τέλος, όταν έχουμε μόνο μια παράμετρο μπορούμε να παραλείψουμε και τις παρενθέσεις.
const increment = a => a + 1
Είναι σημαντικό να σημειωθεί πως δεν υπάρχει καμία λειτουργική διαφορά στις παραπάνω παραλλαγές.
Όπως αναφέρθηκε παραπάνω, μια arrow function δεν δημιουργεί το δικό της context και έχει το ίδιο με το σημείο που έχει γραφτεί. Στην ουσία έχει το ίδιο scope με το σημείο που γράφτηκε και όχι με το σημείο που καλέστηκε.
Πάμε να δούμε μερικά παραδείγματα για να καταλάβουμε καλύτερα πως δουλεύει.
Στο παρακάτω παράδειγμα έχουμε ένα object Person με 3 πεδία. To name, που είναι ένα string, το getName, μια function που επιστρέφει το name και το getAsyncName, μια function που επιστρέφει το name αλλά μετά από 1 δευτερόλεπτο χρησιμοποιώντας τη function setTimeout της JavaScript.
const Person = {
name: "Thanos",
getName: function() {
console.log(this.name);
},
getAsyncName: function() {
setTimeout(function() {
console.log(this.name);
}, 1000);
}
};
Person.getName(); // Thanos
Person.getAsyncName(); // undefinedΣτο παράδειγμα βλέπουμε πως όταν καλούμε τη function getName από το object Person μας επιστρέφει Thanos, την τιμή δηλαδή του name.
Όταν καλούμε την getAsyncName μας επιστρέφει undefined. Αυτό γίνεται διότι η function που υπάρχει μέσα στο setTimeout δεν καλείτε εκείνη τη στιγμή αλλά καλείτε από τον browser μετά από ένα δευτερόλεπτο.
Αν εκτυπώσουμε το this μέσα στη function, θα δούμε πως είναι το window object, δηλαδή το global object που έχει ο browser.
Ας δούμε μερικούς τρόπους για να διορθώσουμε το παραπάνω πρόβλημα, πριν δούμε πως θα δούλευε με μια arrow function.
const Person = {
name: "Thanos",
getName() {
console.log(this.name);
},
getAsyncName() {
let that = this; // Αναθέτουμε το this σε μια καινούργια μεταβλητή that
setTimeout(function() {
console.log(that.name); // Χρησιμοποιούμε τη μεταβλητή that αντί για το this.
}, 1000);
}
};
Person.getName(); // Thanos
Person.getAsyncName(); // ThanosΑναθέτοντας το this σε μια νέα μεταβλητή και εκτυπώνοντας το name από αυτή βλέπουμε, πως μετά από ένα δευτερόλεπτο θα εκτυπωθεί Thanos. Αυτό γίνεται λόγω μια λειτουργίας της JavaScript που ονομάζεται closures.
Με απλά λόγια η λειτουργία αυτή είναι όταν μια function έχει πρόσβαση στις μεταβλητές που υπάρχουν έξω από αυτήν ακόμα και αν έχει τελειώσει η εκτέλεση της. Έτσι, ακόμα και αν η function δεν καλείτε εκείνη τη στιγμή, έχει ακόμα πρόσβαση στη μεταβλητή that.
const Person = {
name: "Thanos",
getName() {
console.log(this.name);
},
getAsyncName() {
setTimeout(
function() {
console.log(this.name);
}.bind(this), // Κάνουμε bind τη function στο this της getAsyncName.
1000
);
}
};
Person.getName(); // Thanos
Person.getAsyncName(); // ThanosΟ επόμενος τρόπος είναι να κάνουμε bind το this εμείς στη function. Έτσι, ακόμα και αν καλεστεί από αλλού η function, έχουμε καθορίσει εμείς το context που θα έχει από όπου και αν καλεστεί.
const Person = {
name: "Thanos",
getName() {
console.log(this.name);
},
getAsyncName() {
setTimeout(() => {
console.log(this.name);
}, 1000);
}
};
Person.getName(); // Thanos
Person.getAsyncName(1000); // ThanosΧρησιμοποιώντας arrow function αντί για function, το πρόβλημα λύνεται. Όταν καλεστεί από τον browser, μετά από ένα δευτερόλεπτο, δε θα δημιουργήσει δικό της context αλλά θα χρησιμοποιήσει εκείνο της getAsyncName.
const Person = {
name: "Thanos",
getName: () => {
console.log(this.name);
},
getAsyncName: () => {
setTimeout(() => {
console.log(this.name);
}, 1000);
}
};
Person.getName(); // undefined
Person.getAsyncName(); // undefinedΕπειδή όμως η arrow function δε δημιουργεί δικό της context, στην παραπάνω περίπτωση θα εκτυπωθεί και στις 2 περιπτώσεις undefined. Όπως είπαμε η function δημιουργεί δικό της context από εκεί που καλέστηκε. Στην περίπτωση μας στο Person object και έτσι γνωρίζει για το πεδίο name. Αν εκτυπώσουμε το this μέσα από τις 2 arrow functions, θα δούμε πως είναι το Window object, δηλαδή το global state.
Μπορούμε να χρησιμοποιήσουμε μια μεταβλητή σαν key/value ενός object.
const name = "Thanos";
const obj = { name }; // Αντί για { name: name };.Το object destructuring μας επιτρέπει να τραβήξουμε κάποιες τιμές από ένα object και να τις αναθέσουμε σε μεταβλητές.
Ο τρόπος για να εξάγουμε αυτές τις τιμές, είναι δηλώνοντας μέσα σε άγκιστρα { } τα κλειδιά που θέλουμε από το object.
const user = {
id: 1,
name: "Thanos",
age: 26,
email: "korakas@socialnerds.gr"
};
// Σε αυτή την περίπτωση θα πάρουμε τις τιμές name και email από το object user.
const { name, email } = user;
console.log(name, email); // Thanos korakas@socialnerds.grΜια χρήση του object destructuring είναι για να πάρουμε μόνος τις τιμές που θέλουμε από ένα object που περάστηκε σαν παράμετρος σε μια function.
const user = {
id: 1,
name: "Thanos",
age: 26,
email: "korakas@socialnerds.gr"
};
function printName({ name }) {
console.log(name);
}
printName(user);Το array destructuring δουλεύει παρόμοια με το object destructuring. Επειδή όμως στο array τα κλειδιά είναι το index number (ουσιαστικά ένας αύξων αριθμός), δεν μπορούμε να τραβήξουμε όποια τιμή θέλουμε, αλλά πρέπει να την πάρουμε με σειρά. Ας δούμε ένα παράδειγμα:
const names = ["Thanos", "Dimitris", "Natalia", "Georgia"];
const [first, second] = names;
console.log(first, second); // Thanos, DimitrisΜε αυτό τον τρόπο, θα αναθέσουμε την πρώτη τιμή του πίνακα names (Thanos) στη μεταβλητή first και τη δεύτερη τιμή (Dimitris) στη μεταβλητή second.
Χρησιμοποιούμε spread operator, όταν θέλουμε να δημιουργήσουμε ένα καινούργιο object ή array χρησιμοποιώντας τις τιμές από ένα ήδη υπάρχον object ή array. Η σύνταξη είναι πολύ απλή και το μόνο που πρέπει να κάνουμε είναι να προσθέσουμε τρεις τελείες μπροστά από το object ή το array: ...{name: 'Thanos', age: 26}, ...[1, 2, 3].
Μπορούμε να φανταστούμε, πως αυτό που κάνει ο spread operator είναι ότι αφαιρεί τον container, δηλαδή τις αγκύλες σε περίπτωση array ή τα άγκιστρα σε περίπτωση object, με αποτέλεσμα να μπορούμε να χρησιμοποιήσουμε τις τιμές σε ένα νέο object ή array.
Για να δούμε μερικά παραδείγματα για το πως δουλεύει:
const numbers = [1, 2, 3];
const moreNumbers = [...numbers, 4, 5, 6];
console.log(moreNumbers); // 1, 2, 3, 4, 5, 6
console.log(numbers); // 1, 2, 3Επίσης, είναι σημαντικό να σημειώσουμε πως δεν υπάρχει κανένα reference στον παλιό πίνακα, οπότε αν προσθέσουμε κάτι στον πρώτο πίνακα δεν θα εμφανιστεί στον καινούργιο.
const user = {
id: 3,
name: "Thanos"
};
const newObject = { ...user, age: 26, email: "korakas@socialnerds.gr" };
console.log(newObject);
/**
* Output
* {
* id: 3,
* name: "Thanos",
* age: 26,
* email: "korakas@socialnerds.gr"
* }
*/Μια συνηθισμένη χρήση του spread operator είναι όταν θέλουμε να αλλάξουμε ένα πεδίο από το object δημιουργώντας ένα νέο object (immutability).
const user = {
id: 2,
name: "Thanos"
};
const updatedUser = {
...user,
name: "Dimitris"
};
console.log(user);
/**
* Output
* {
* id: 3,
* name: "Thanos",
* }
*/
console.log(updatedUser);
/**
* Output
* {
* id: 3,
* name: "Dimitris",
* }
*/Ο rest operator μπορεί να μοιάζει με τον spread operator, αλλά αντί να δημιουργεί νέα arrays ή objects χρησιμοποιείται για να σπάσει arrays ή objects σε μικρότερα κομμάτια.
Η σύνταξη είναι πάλι η ίδια, προσθέτουμε τρεις τελείες μπροστά από τη μεταβλητή που θέλουμε να το χρησιμοποιήσουμε.
Πριν χρησιμοποιήσαμε destructuring για να τραβήξουμε κάποιες τιμές από ένα object ή array. Τώρα θα δούμε πως μπορούμε να πάρουμε τις τιμές που θέλουμε αλλά και όλες τις υπόλοιπες, χρησιμοποιώντας τον rest operator.
const user = {
id: 2,
name: 'Thanos',
age: 26
};
// const { name } = user; Αναθέτουμε την τιμή name του object user στην σταθερά name.
const { name, ...rest } = user; // Κάνουμε το ίδιο για το name αλλά τώρα αναθέτουμε όλες τις άλλες τιμές στη σταθερά rest. Το rest είναι απλά ένα όνομα μεταβλητής, θα μπορούσα να είναι οτιδήποτε.
console.log(name); // Thanos
console.log(rest);
/**
* Output
* {
* id: 2,
* age: 26
* }Μπορούμε να κάνουμε το ίδιο με πίνακες.
Επιπλέον, μπορούμε να χρησιμοποιήσουμε τον rest operator για να πάρουμε όλες τις παραμέτρους που περνάμε σε μια function.
Παρακάτω βλέπουμε τι κάνει η reduce function παρακάτω.
function coolSum(...numbers) {
return numbers.reduce((sum, number) => sum + number, 0);
}
console.log(coolSum(1, 2, 3, 4, 5)); // 15function log(severity, ...messages) {
console[severity](messages);
}
log("table", "Hello", "Nerds", "!");Πλέον στην JavaScript υπάρχουν μερικές functions που κάνουν τη διαχείριση των arrays πολύ εύκολη. Είναι σημαντικό να θυμόμαστε πως αυτές οι functions δεν επηρεάζουν το υπάρχον array αλλά δημιουργούν ένα νέο.
Ο τρόπος σύνταξης για αυτές τις functions είναι κοινός. Σε ένα υπάρχον array καλούμε τη function χρησιμοποιώντας . και το όνομα της function: .filter(), .map(), .find(), .reduce(). Στη συνέχεια, περνάμε σαν παράμετρο μια function που παίρνει σαν παράμετρο ένα ένα τα στοιχεία του πίνακα.
Σκεφτείτε το σαν ένα for loop. Η συνάρτηση κάνει μια επανάληψη στον πίνακα και μας δίνει ένα ένα τα στοιχεία ώστε να τα επεξεργαστούμε.
Η συνάρτηση filter μας επιτρέπει να δημιουργήσουμε ένα νέο array φιλτράροντας μόνο τις τιμές που θέλουμε από ένα υπάρχον.
Σε κάθε επανάληψη επιστρέφουμε true ή false. Αν επιστρέψουμε true, το τρέχον στοιχείο της επανάληψης θα επιστραφεί στον νέο πίνακα.
const numbers = [10, 40, 150, 30, 60, 100];
const filteredNumbers = numbers.filter(function(number) {
// Εδώ βλέπουμε πως η μεταβλητή number είναι το τρέχον στοιχείο του πίνακα.
// Επιστρέφουμε true αν η τρέχουσα τιμή είναι μεγαλύτερη του 50.
return number > 50;
});
console.log(numbers); // 10, 40, 150, 30, 60, 100
console.log(filteredNumbers); // 150, 60, 100Η συνάρτηση map μας επιτρέπει να δημιουργήσουμε ένα νέο array μετασχηματίζοντας ένα υπάρχον.
Σε κάθε επανάληψη επιστρέφουμε τη νέα τιμή που θέλουμε να έχει ο νέος πίνακας.
const colors = ["red", "blue", "green", "purple"];
const transformedColors = colors.map(function(color) {
return color.toUpperCase();
});
console.log(colors); // 'red', 'blue', 'green', 'purple'
console.log(transformedColors); // 'RED', 'BLUE', 'GREEN', 'PURPLE'Η συνάρτηση find μας επιστρέφει το στοιχείο του πίνακα που ικανοποιεί κάποιες συνθήκες.
Σε κάθε επανάληψη επιστρέφουμε false ή true αν βρήκαμε το στοιχείο που θέλουμε και διακόπτουμε την επανάληψη.
const users = [
{
id: 1,
name: "Thanos K."
},
{
id: 2,
name: "Thanos N."
},
{
id: 3,
name: "Dimitris"
}
];
const user = users.find(function(user) {
return user.id === 1;
});
console.log(user.name); // 'Thanos K.';Η συνάρτηση reduce μας επιστρέφει μια τιμή μετασχηματίζοντας τον υπάρχον πίνακα.
const numbers = [0, 1, 2, 3, 5, 8, 13, 21, 34];
// Η function reduce σε διαφορά με τις προηγούμενες παίρνει 2 παραμέτρους.
// Η 1η παράμετρος είναι όπως στις προηγούμενος μια function με τις εξής παραμέτρους
// - 1η είναι η τιμή από τις προηγούμενες επαναλήψεις
// - 2η είναι η τρέχουσα τιμή της επανάληψης
// reduce(fn(a, b), c);
const sum = numbers.reduce(function(acc, current) {
// Επιστρέφουμε το άθροισμα όλων τον προηγούμενων επαναλήψεων + την τιμή της τρέχουσας επανάληψης.
return acc + current;
// Η reduce δέχεται μια 2η παράμετρο που είναι η αρχική τιμή που θα έχει η μεταβλητή acc κατά την πρώτη επανάληψη.
}, 0);
console.log(sum); // 87Οι παραπάνω functions τρέχουν σε array οποιουδήποτε τύπου και όχι μόνο σε όσα υπάρχουν στα παραπάνω παραδείγματα.
Στις νέες εκδόσεις της JavaScript έχουμε τη δυνατότητα να χωρίσουμε τον κώδικα μας σε μικρά επαναχρησιμοποιήσιμα αρχεία. Αυτά τα αρχεία ονομάζονται modules. Για να μπορέσουμε να δημιουργήσουμε ένα module πρέπει να ορίσουμε τον τρόπο με τον οποίο ενα module θα μπορεί να χρησιμοποιήσει ένα άλλο.
Ας ξεκινήσουμε με το πως μπορούμε να εξάγουμε τον κώδικά μας.
Έστω πως έχουμε φτιάξει μια function που προσθέτει 2 αριθμούς.
function add(a, b) {
return a + b;
}Για να εξάγουμε τη function add θα πρέπει να χρησιμοποιήσουμε το keyword export.
export function add(a, b) {
return a + b;
}Για να μπορέσουμε τώρα να χρησιμοποιήσουμε αυτή τη function σε ένα άλλο αρχείο θα πρέπει να το δηλώσουμε στην αρχή του αρχείου χρησιμοποιώντας το keyword import.
import { add } from ‘./add’;
console.log(add(1, 2)); // 3Αρχικά, χρησιμοποιούμε destructuring όπως είδαμε παραπάνω για να εξάγουμε τη function add από το αρχείο add.
Στη συνέχεια, πρέπει να δηλώσουμε από που πρέπει να γίνει import η function add. Αυτό το κάνουμε χρησιμοποιώντας το keyword from και στη συνέχεια το όνομα του αρχείου. Είναι σημαντικό να προσθέσουμε ./ που δηλώνει πως το αρχείο βρίσκεται στον ίδιο φάκελο ή να δηλώσουμε το relative path του αρχείου.
Ας δούμε ένα παράδειγμα με μια διαφορετική δομή αρχείων.
utils
- add.js
lib
- tax.js
Σε αυτό το παράδειγμα θέλουμε να χρησιμοποιήσουμε τη function add στο αρχείο tax.js. Για να κάνουμε import θα έπρεπε να γράψουμε το παρακάτω.
import { add } from ‘../utils/add’;
Ο λόγος που ακόμα και αν βρισκόμαστε στον ίδιο φάκελο πρέπει να προσθέσουμε ./ είναι διότι αν δεν υπάρχει κάποιο path η JavaScript νομίζει πως θέλουμε να κάνουμε import κάποια βιβλιοθήκη την οποία κατεβάσαμε και βρίσκεται στον φάκελο node_modules.
Όταν θέλουμε να κάνουμε import μια βιβλιοθήκη που έχουμε κατεβάσει, ας πούμε πως αυτή είναι η React, θα κάνουμε το παρακάτω:
import React from ‘react’;
Σε αυτή την περίπτωση θα ψάξει τη React στον φάκελο node_modules που έχει δημιουργηθεί κατά την εγκατάσταση της React χρησιμοποιώντας το npm ή το yarn.
Πίσω στο θέμα μας, import και export, πάμε να δούμε μερικά ακόμα παραδείγματα.
Στο παράδειγμα με τη React, δε χρειάστηκε να χρησιμοποιήσουμε destructuring για να εξάγουμε τη βιβλιοθήκη.
Για να το κάνουμε αυτό πρέπει να δηλώσουμε ένα default export από το αρχείο μας.
Ας δούμε πως γίνεται αυτό.
export default function add(a, b) {
return a + b;
}Μπορούμε ακόμα και να παραλείψουμε το όνομα της function αν κάνουμε default export.
export default function(a, b) {
return a + b;
}Πλέον μπορούμε να το χρησιμοποιήσουμε έτσι: import add from ‘./add’;
Μπορούμε να κάνουμε μόνο ένα export default από ένα αρχείο, αλλά μπορούμε να κάνουμε πολλά exports.
export function add(a, b) {
return a + b;
}
export function sub(a, b) {
return a - b;
}
export function avg(...numbers) {
const sum = avg.reduce((acc, number) => acc + number, 0);
return sum / numbers.length;
}Τώρα μπορούμε να κάνουμε import όποια function θέλουμε χρησιμοποιώντας destructuring.
import { add, sub } from ‘./math’;
Μετονόμασαμε το αρχείο add.js σε math.js γιατί πλέον έχει και άλλες functions.
Μπορούμε να κάνουμε import όλες τις συναρτήσεις που γίνονται export στο αρχείο math με τον παρακάτω τρόπο:
Import * as math from ‘./math’;
console.log(math.add(1, 2)); // 3- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
- https://flaviocopes.com/javascript-loops-map-filter-reduce-find/
- https://flaviocopes.com/javascript-array
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules