6 funzionalità JavaScript che dovresti conoscere
Pubblicato: 2020-09-24Poco più di un anno fa abbiamo parlato delle 5 “nuove” funzionalità JavaScript che dovresti conoscere per sviluppare comodamente in Gutenberg. Lì abbiamo imparato cosa sono la destrutturazione di oggetti e array, come creare funzioni freccia, quali sono gli operatori spread e rest e così via. Fortunatamente, JavaScript ha ancora molte funzionalità che, una volta che le avrai familiari, ti aiuteranno a scrivere codice più intelligibile e conciso.
Oggi ti mostrerò sei funzionalità JavaScript davvero interessanti. Operatori, scoping variabile, promesse, funzioni asincrone... sei pronto per impararle tutte?
#1 Concatenamento opzionale in JavaScript con l'operatore ?.
L'operatore di concatenamento facoltativo consente l'accesso semplificato agli attributi di un oggetto quando è possibile che uno sia undefined o null . Ad esempio, supponiamo di avere un oggetto come il seguente:
const toni = { name: 'Antonio', details: { age: 35, }, }; Per accedere age di toni , devi prima accedere all'attributo details e poi age :
function getAge( person ) { return person.details.age; } Il problema che abbiamo nella funzione precedente, e sono sicuro che non è una novità per te, è che le proprietà che ci aspettiamo che la person abbia non sono sempre lì. Cioè se person o person.details è undefined , la funzione sopra attiverà un errore di tipo:
getAge( toni ); // 35 getAge( {} ); // Uncaught TypeError: person.details is undefinedDi solito, risolviamo questo problema aggiungendo alcune protezioni di sicurezza:
function getAge( person ) { if ( ! person ) { return; } if ( ! person.details ) { return; } return person.details.age; } getAge( toni ); // 35 getAge( {} ); // undefined che lo risolvono chiaramente. Sfortunatamente, la funzione risultante è più complessa e contiene molto codice rumoroso che distoglie la nostra attenzione dalle cose che contano davvero. Per tornare in carreggiata e risolvere la soluzione in modo più semplice, tutto ciò che dobbiamo fare è utilizzare l'operatore di concatenamento opzionale ?. :
function getAge( person ) { return person?.details?.age; } getAge( toni ); // 35 getAge( {} ); // undefined In sostanza, questo operatore ci consente di accedere a ciascuna proprietà purché non sia undefined o null . Non appena rileva che proviamo ad accedere a una proprietà di un oggetto non esistente, restituisce undefined .
# 2 Operatore di Coalescenza Nullish ( ?? )
In JavaScript è molto facile impostare un valore predefinito su una variabile usando questo operatore: || , Giusto? Sbagliato! L'abbiamo fatto tutti, ma può causare effetti collaterali inaspettati se non stai attento...
Ad esempio, supponiamo di avere un selettore nel nostro negozio Redux che ci consente di recuperare un valore impostato dall'utente. Se l'utente non ha ancora specificato un valore (ovvero, il valore è undefined ), restituiamo un valore predefinito utilizzando || :
function getValue( state ) { return state.value || 5; }Ora, vediamo alcuni esempi di ciò che otterremmo con la funzione precedente dopo che l'utente ha impostato un valore o un altro:
// No setValue( x )... getValue(); // 5 setValue( 2 ); getValue(); // 2 setValue( 1 ); getValue(); // 1 setValue( 0 ); getValue(); // 5 Ops! Tutto ha funzionato bene fino a quando non abbiamo raggiunto l'ultimo caso! Apparentemente, se l'utente imposta il valore su 0 , il risultato della funzione diventa 5 . Come mai? Ebbene, la logica è piuttosto ambigua: x||y restituisce y se, e solo se, x è un valore "falso". Questo di solito funziona bene, poiché undefined è un valore falso. Ma anche false o 0 , per esempio.
In realtà, volevamo impostare un valore default solo quando non ce n'è. Quindi possiamo aggiungere una protezione per verificare se c'è un valore o meno:
function getValue( state ) { if ( undefined === state.value ) return 5; return state.value; }e possiamo anche scriverlo usando l'operatore ternario se ci sentiamo fantasiosi:
function getValue( state ) { return undefined === state.value ? 5 : state.value; } ma, ancora una volta, entrambe le soluzioni complicano inutilmente il codice. Per assegnare un valore predefinito a una variabile, dobbiamo utilizzare l'operatore di coalescenza nullo ?? , che restituisce la parte destra se, e solo se, la parte sinistra è null o undefined :
function getValue( state ) { return state.value ?? 5; }e, sorpresa-sorpresa!, il risultato è esattamente quello che volevamo:
// No setValue( x )... getValue(); // 5 setValue( 2 ); getValue(); // 2 setValue( 1 ); getValue(); // 1 setValue( 0 ); getValue(); // 0Oh, e, a proposito, puoi usare questo operatore combinato con un compito. Ad esempio, questo:
value = value ?? 5;è equivalente a questo:
value ??= 5;# 3 Promesse e funzioni asincrone
Le promesse sono un meccanismo implementato in JavaScript che ci consente di semplificare il nostro codice sorgente quando si lavora con operazioni asincrone, cioè operazioni i cui risultati non sono immediatamente disponibili. Ad esempio, se vogliamo recuperare i dati dal nostro server, è chiaro che la risposta non sarà istantanea, poiché dobbiamo attendere che il server riceva la richiesta, la elabori e ci restituisca la risposta.
Nelle versioni e librerie JavaScript precedenti (ad esempio jQuery) lo implementavamo con i callback. L'idea era abbastanza semplice: definire insieme alla richiesta stessa la funzione (il callback) che dovrebbe essere chiamata una volta che la risposta è disponibile. In questo modo, al termine dell'operazione asincrona (cioè il recupero dei dati dal server), la libreria chiamerà la funzione e la nostra logica riprenderà:
jQuery.ajax( { url: 'https://server.com/wp-json/wp/users/1', success: ( user ) => { console.log( user ); }, } );Se stiamo attivando solo una singola richiesta isolata, questa soluzione è abbastanza elegante e conveniente. Ma, non appena abbiamo bisogno di eseguire più richieste, le cose si sporcano rapidamente. Ad esempio, se vogliamo richiedere due utenti diversi, dovremmo annidare i callback:

jQuery.ajax( { url: 'https://server.com/wp-json/wp/v2/users/1', success: ( user1 ) => { jQuery.ajax( { url: 'https://server.com/wp-json/wp/v2/users/2', success: ( user2 ) => { console.log( user1, user2 ); }, } ); }, } );Le promesse sono la soluzione a questo problema: se ottenere un determinato risultato non è immediato (come, ad esempio, quando recuperiamo qualcosa da un server), possiamo restituire subito una promessa JavaScript. Questo oggetto è un involucro del valore effettivo e indica la "promessa" che detto valore sarà disponibile in futuro.
Ad esempio, se dovessimo riscrivere il nostro primo snippet usando le promesse, sarebbe simile a questo:
const promise = wp.apiFetch( { url: 'https://server.com/wp-json/wp/v2/users/1', } ); promise.then( ( user ) => console.log( user ) ); Come puoi vedere, wp.apiFetch deve recuperare l'utente 1 dal server, ma fornisce immediatamente un risultato. Il risultato, tuttavia, non è l'utente stesso, ma una promessa che si risolverà all'utente una volta completate le richieste. Pertanto, tutto ciò che dobbiamo fare è scrivere un callback che elaborerà la risposta della promessa quando sarà risolta.
Ora potresti pensare che questo non è così difficile da quello che avevamo prima, giusto? Dopotutto, stiamo ancora utilizzando i callback... ma puoi vedere quanto sia utile una volta che iniziamo a combinare più richieste:
const promise1 = wp.apiFetch( { url: 'https://server.com/wp-json/wp/v2/users/1', } ); const promise2 = wp.apiFetch( { url: 'https://server.com/wp-json/wp/v2/users/2', } ); Promise.all( [ promise1, promise2 ] ).then( ( [ user1, user2 ] ) => console.log( user1, user2 ); ); Utilizzando le promesse, siamo stati in grado di avviare due richieste parallele per recuperare gli utenti 1 e 2 e utilizzare Promise.all per attendere la risoluzione di entrambe le promesse. Nessun codice spaghetti con callback nidificati coinvolti.
Bene, il bello delle promesse sta ancora per arrivare. Possiamo usare un po' di zucchero sintattico per lavorare con le promesse JavaScript e scrivere codice asincrono che sembra, beh, sincrono. Tutto quello che devi fare è definire una funzione asincrona usando la parola chiave async e improvvisamente le cose diventano molto, molto più semplici:
async function logTwoUsers( id1, id2 ) { const user1 = await wp.apiFetch( { url: '…' + id1 } ); const user2 = await wp.apiFetch( { url: '…' + id2 } ); console.log( user1, user2 ); } Ogni volta che chiami un'operazione asincrona all'interno di una funzione asincrona, puoi attendere il suo risultato usando la parola chiave await . L'unica cosa che dovresti tenere a mente è che, quando definisci una funzione async , il suo risultato sarà sempre una promessa:
async function getNumberFive() { return 5; } const p = getNumberFive(); // a promise p.then( console.log ); // prints "5" # 4 Ambito variabile quando si usa let e const
Come probabilmente già saprai, ora puoi dichiarare variabili usando le parole chiave let e const . Il primo definisce una variabile e il secondo definisce una costante:
let x = 1; console.log( x ); // 1 x = 2; console.log( x ); // 2 const y = 1; console.log( y ); // 1 y = 2; // Uncaught TypeError: invalid assignment to const 'y' console.log( y ); // 1 Potresti essere tentato di pensare che let e var siano la stessa cosa, poiché entrambe le parole chiave ci consentono di dichiarare una variabile non costante. Ma c'è una differenza sostanziale tra loro: la loro portata. Con let e const , l'ambito della variabile è il blocco in cui è definita. In var , è l'intera funzione.
function fn() { if ( true ) { var x = 1; let y = 2; const z = 3; }//end if console.log( x ); // 1 console.log( y ); // Uncaught ReferenceError: y is not defined console.log( z ); // Uncaught ReferenceError: z is not defined } # 5 Trasformazione dei dati quando si utilizza JSON.parse
La funzione JSON.parse analizza una stringa JSON e crea un oggetto JavaScript. Per esempio:
const x = JSON.parse( '{"x":1,"a":[1,2,3]}' ); // Object { x: 1, a: [ 1, 2, 3 ] } Quello che la maggior parte delle persone non sa è che supporta un secondo argomento chiamato reviver . Questo parametro è una funzione che verrà eseguita per ogni elemento che viene analizzato, consentendoti di manipolare il valore a tuo piacimento. Ad esempio, immagina una stringa JSON come la seguente:
const json = '{"name":"David","birthday":"1985-12-01T10:00:00.000Z"}'; Se utilizziamo JSON.parse così com'è, genererà un oggetto con due attributi di stringa: name e birthday . Ma se forniamo una funzione di JSON.parse reviver possiamo assicurarci che il birthday venga analizzato come Date :
const user = JSON.parse( json, ( key, value ) => 'birthday' === key ? new Date( value ) : value ) # 6 Separatore numerico nel codice sorgente utilizzando il carattere Undesrcore ( _ )
Il nostro ultimo consiglio oggi è il separatore numerico. C'è una proposta (attualmente nella fase 4) che consente di scrivere numeri in un modo che rende più facile la comprensione per gli esseri umani. Ad esempio, puoi davvero dire quanto sono grandi i seguenti numeri?
10000000000 2189719.25 Se solo potessimo usare il separatore delle migliaia, sarebbe molto più facile da interpretare! Ed è esattamente quello che possiamo fare usando il trattino basso _ :
10_000_000_000 2_189_719.25Sommario
È possibile scrivere codice JavaScript migliore se ti abitui a tutti i nuovi strumenti e funzionalità inclusi in JavaScript. Oggi abbiamo visto diversi esempi di ciò che è possibile fare con questo linguaggio di programmazione. Spero che tu abbia imparato qualcosa di nuovo e se ti è piaciuto, non dimenticare di condividerlo con i tuoi colleghi. Ci vediamo presto!
Immagine in primo piano di Sam Dan Truong su Unsplash.
