12 trucchi JavaScript che non troverai mai nella maggior parte dei tutorial
Quando ho iniziato a studiare JavaScript, mi sono reso subito conto che, avere una buona conoscenza dei costrutti fondamentali di questo linguaggio, mi avrebbe portato a risparmiare molto tempo durante la fase di programmazione.
Così ho fatto un elenco di tutti questi trucchi, utili per uno sviluppo agile, che ho trovato nel codice scritto da altri, nei vari siti Web, come ad esempio stack overflow e in qualsiasi altro posto diverso dai convenzionali tutorial che ho usato fino a quel momento.
Da allora aggiorno questo elenco e, in questo articolo, condividerò 12 suggerimenti scelti a mano che mi sembrano particolarmente intelligenti o utili. Questo post vuole essere utile per i principianti, ma spero che anche gli sviluppatori JavaScript più esperti trovino qualcosa di utile.
Mentre molti di questi trucchi sono utili in qualsiasi contesto, alcuni di essi possono essere più adatti al codice a livello di produzione, dove la chiarezza è spesso importante tanto quanto la concisione.
Quindi, in nessun ordine particolare, ecco 12 modi per scrivere codice più conciso e più performante.
Indice del Post...
1. Filtro valori univoci
ARRAYS
Il Set
(tipo oggetto) è stato introdotto in ES6 e, possiamo usarlo per creare un nuovo array con solo valori univoci.
const array = [1, 1, 2, 3, 5, 5, 1] const uniqueArray = [new Set(array)]; console.log(uniqueArray); // Result: [1, 2, 3, 5]
Prima di ES6, isolare valori univoci avrebbe comportato molto più codice di questo!
Questo trucco funziona per gli array che contengono tipi primitivi: undefined
, null
, boolean
, string
e number
. (Se avessi un array contenente oggetti, funzioni o array aggiuntivi, avresti bisogno di un approccio diverso!)
2. Valutazione del corto circuito
CONDIZIONALI
L’operatore ternario è un modo rapido per scrivere istruzioni condizionali semplici (e talvolta non così semplici), come queste:
x>100 ? 'maggiore di 100' : 'inferiore a 100'; x>100 ? (x>200 ? 'maggiore di 200' : 'fra 100 e 200') : 'minore di 100';
Ma a volte anche l’operatore ternario è più complicato del necessario. Invece, possiamo usare gli operatori logici ‘AND’ &&
e ‘OR’ ||
per valutare determinate espressioni in un modo ancora più conciso. Questo è spesso chiamato “cortocircuito” o “valutazione del cortocircuito”.
Come funziona
Diciamo che vogliamo restituire solo una delle due o più opzioni.
utilizzando &&
restituirà il primo false
o valore “falso”.Se ogni operando viene valutato true
, verrà restituita l’ultima espressione valutata.
let one = 1, two = 2, three = 3; console.log(one && two && three); // Result: 3 console.log(0 && null); // Result: 0
L’utilizzo ||
restituirà il primo true
o il valore “verità”. Se ogni operando viene valutato false
, verrà restituita l’ultima espressione valutata.
let one = 1, two = 2, three = 3; console.log(one || two || three); // Result: 1 console.log(0 || null); // Result: null
Esempio 1
Diciamo che vogliamo restituire il length
di una variabile, ma non conosciamo il tipo di variabile.
Potremmo usare if/else
un’istruzione per verificare che foo
sia un tipo accettabile, ma questo potrebbe essere piuttosto lungimirante. La valutazione del corto circuito ci consente invece di fare questo:
return (foo || []).length;
Se la variabile foo
è vera, verrà restituita. Altrimenti, la length
dell’array vuoto verrà restituito: 0
.
Esempio 2
Hai mai avuto problemi di accesso a una proprietà di oggetto nidificato? Potresti non sapere se esiste l’oggetto o una delle sotto-proprietà e questo può causare errori frustranti.
Supponiamo di voler accedere a una proprietà chiamata data
all’interno this.state
, ma data
non è definita fino a quando il nostro programma non ha restituito correttamente una richiesta di recupero.
A seconda di dove la utilizziamo, la chiamata this.state.data
potrebbe impedire l’esecuzione della nostra app. Per aggirare questo, potremmo avvolgerlo in un condizionale:
if (this.state.data) {
return this.state.data;
} else {
return 'Fetching Data';
}
Ma sembra abbastanza ripetitivo. L’operatore ‘o’ fornisce una soluzione più concisa:
return (this.state.data || 'Fetching Data');
Non possiamo modificare il codice sopra per usare &&
. La dichiarazione 'Fetching Data' && this.state.data
restituirà this.state.data
se lo è undefined
o meno. Questo perché 'Fetching Data'
è “vero”, e quindi lo &&
passerà sempre quando viene elencato per primo.
Una nuova caratteristica proposta: concatenamento opzionale
Al momento esiste una proposta per consentire il “concatenamento opzionale” quando si tenta di restituire una proprietà in profondità in una struttura ad albero. In base alla proposta, il simbolo del punto interrogativo ?
potrebbe essere utilizzato per estrarre una proprietà solo se non lo è null
.
Ad esempio, potremmo rifattorizzare il nostro esempio sopra this.state.data?.()
, ritornando così solo data
se non lo è null
.
Oppure, se fossimo principalmente preoccupati del fatto che state
fosse definito o meno, potremmo tornare this.state?.data
.
La proposta è attualmente in fase 1, come funzionalità sperimentale. Puoi leggerlo qui , e puoi usarlo nel tuo JavaScript ora tramite Babel, aggiungendo @ babel / plugin-proposta-optional-concatenamento al tuo .babelrc
file.
3. Converti in booleano
CONVERSIONE DI TIPO
Oltre ai normali valori booleani true
e false
, JavaScript considera anche tutti gli altri valori come “verità” o “falsa”.
Salvo diversamente definito, tutti i valori in JavaScript sono ‘truthy’ con l’eccezione di 0
, ""
, null
, undefined
, NaN
e, naturalmente false
, che sono ‘falsy’.
Possiamo facilmente passare da vero a falso usando l’operatore negativo !
, che convertirà anche il tipo in "boolean"
.
const isTrue = !0; const isFalse = !1; const alsoFalse = !!0; console.log(isTrue); // Result: true console.log(typeof true); // Result: "boolean"
Questo tipo di conversione di tipo può essere utile in istruzioni condizionali, anche se l’unico motivo che ci si sceglie di definire false
come !1
è se si stesse giocando codice di golf!
4. Converti in stringa
CONVERSIONE DI TIPO
Per convertire rapidamente un numero in una stringa, possiamo usare l’operatore di concatenazione +
seguito da una serie vuota di virgolette ""
.
const val = 1 + ""; console.log(val); // Result: "1" console.log(typeof val); // Result: "string"
5. Converti in numero
CONVERSIONE DI TIPO
È possibile ottenere rapidamente il contrario utilizzando l’operatore addizione +
.
let int = "15"; int = +int;console.log(int); // Result: 15 console.log(typeof int); Result: "number"
Questo può anche essere usato per convertire i booleani in numeri, come di seguito:
console.log(+true); // Return: 1 console.log(+false); // Return: 0
Ci possono essere contesti in cui la +
volontà verrà interpretata come l’operatore di concatenazione piuttosto che l’operatore di addizione. Quando ciò accade (e si desidera restituire un intero, non un galleggiante) si può invece utilizzare la doppia tilde: ~~
.
Una tilde, nota come “operatore NOT bit a bit”, è un operatore equivalente a -n — 1
. Quindi, per esempio, ~15
è uguale a -16
.
L’uso di due tilde di fila annulla efficacemente l’operazione, perché — ( — n — 1) — 1 = n + 1 — 1 = n
. In altre parole, è ~ — 16
uguale 15
.
const int = ~~ "15"; console.log (int); // Risultato: 15 console.log (typeof int); Risultato: "numero"
Sebbene non riesca a pensare a molti casi d’uso, l’operatore NOT bit a bit può essere utilizzato anche su valori booleani: ~true = -2
e ~false = -1
.
6. Poteri rapidi
OPERAZIONI
Da ES7, è stato possibile utilizzare l’operatore di esponenziazione **
come scorciatoia per i poteri, che è più veloce della scrittura Math.pow(2, 3)
. Questa è una cosa semplice, ma rende l’elenco perché non sono stati aggiornati molti tutorial per includere questo operatore!
console.log (2 ** 3); // Risultato: 8
Questo non deve essere confuso con il ^
simbolo, comunemente usato per rappresentare esponenti, ma che in JavaScript è l’operatore XOR bit a bit.
Prima di ES7, la stenografia esisteva solo per le potenze con base 2, usando l’operatore di spostamento a sinistra bit a bit <<
:
// Le seguenti espressioni sono equivalenti: Math.pow (2, n);
2 << (n - 1);
2 ** n;
Ad esempio, 2 << 3 = 16
equivale a 2 ** 4 = 16
.
7. Float rapido su intero
OPERAZIONI / CONVERSIONE DEL TIPO
Se si desidera convertire un galleggiante in un intero, è possibile utilizzare Math.floor()
, Math.ceil()
o Math.round()
. Ma c’è anche un modo più veloce per troncare un float su un numero intero usando |
, l’operatore OR bit a bit.
console.log (23.9 | 0); // Risultato: 23
console.log (-23.9 | 0); // Risultato: -23
Il comportamento di |
varia a seconda che tu abbia a che fare con numeri positivi o negativi, quindi è meglio usare questa scorciatoia se sei sicuro.
Se n
è positivo, n | 0
arrotonda per difetto. Se n
è negativo, arrotonda per eccesso. Per dirla con maggiore precisione, questa operazione rimuove tutto ciò che segue il punto decimale, troncando un float su un numero intero.
Puoi ottenere lo stesso effetto di arrotondamento usando ~~
, come sopra, e in effetti qualsiasi operatore bit a bit forzerebbe un float a un numero intero. La ragione per cui queste particolari operazioni funzionano è che – una volta forzato a un numero intero – il valore rimane invariato.
Rimuovi cifre finali
L’operatore OR bit a bit può anche essere utilizzato per rimuovere qualsiasi quantità di cifre dalla fine di un numero intero. Ciò significa che non è necessario utilizzare codice come questo per la conversione tra tipi:
let str = "1553"; Number(str.substring(0, str.length - 1));
Invece, l’operatore OR bit a bit ci consente di scrivere:
console.log (1553/10 | 0) // Risultato: 155
console.log (1553/100 | 0) // Risultato: 15
console.log (1553/1000 | 0) // Risultato: 1
8. Rilegatura automatica nelle classi
CLASSI
Possiamo usare la notazione con freccia ES6 nei metodi di classe e in questo modo è implicito il legame. Questo spesso salverà diverse righe di codice nel nostro costruttore di classi e possiamo felicemente dire addio ad espressioni ripetitive come !
this.myMethod=this.myMethod.bind(this)
import React, { Component } from React; export default class App extends Compononent { constructor(props) { super(props); this.state = {}; } myMethod = () => { // This method is bound implicitly! } render() { return ( <> <div> {this.myMethod()} </div> </> ) } };
9. Tronca una matrice
ARRAYS
Se si desidera rimuovere i valori dalla fine di un array in modo distruttivo, ci sono alternative più veloci rispetto all’uso splice()
.
Ad esempio, se conosci la dimensione dell’array originale, puoi ridefinire la sua proprietà length, in questo modo:
let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; array.length = 4; console.log (array); // Risultato: [0, 1, 2, 3]
Questa è una soluzione particolarmente concisa. Tuttavia, ho riscontrato che il tempo di esecuzione del slice()
metodo è ancora più veloce. Se la velocità è il tuo obiettivo principale, considera l’utilizzo di qualcosa del genere:
let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; array = array.slice (0, 4); console.log (array); // Risultato: [0, 1, 2, 3]
10. Ottieni gli ultimi elementi in una matrice
ARRAYS
Il metodo array slice()
può accettare numeri interi negativi e, se fornito, prenderà valori dalla fine dell’array anziché dall’inizio.
let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; console.log (array.slice (-1)); // Risultato: [9] console.log (array.slice (-2)); // Risultato: [8, 9] console.log (array.slice (-3)); // Risultato: [7, 8, 9]
11. Formattare il codice JSON
JSON
Infine, potresti averlo usato JSON.stringify
prima, ma ti sei reso conto che può anche aiutarti nel far rientrare il tuo codice JSON per te?
Il stringify()
metodo accetta due parametri opzionali: una replacer
funzione, che è possibile utilizzare per filtrare il JSON visualizzato, e un space
valore.
Il space
valore accetta un numero intero per il numero di spazi desiderato o una stringa (ad esempio '\t'
per inserire le schede) e può rendere molto più semplice la lettura dei dati JSON recuperati.
console.log (JSON.stringify ({alpha: 'A', beta: 'B'}, null, '\ t')); // Risultato: // '{ // "alpha": A, // "beta": B //}'
Nel complesso, spero che tu abbia trovato questi suggerimenti utili come quando li ho scoperti per la prima volta.
Hai qualche trucco JavaScript per conto tuo? Mi piacerebbe leggerli nei commenti qui sotto!
12. Lunghezza della matrice della cache [obsoleta] nei loop
LOOP
Nella versione originale di questo articolo, ho condiviso un suggerimento per memorizzare nella cache la lunghezza dell’array nei for
loop. Tuttavia, se si tratta di un ciclo di sola lettura, i moderni motori JavaScript si occupano di questo al momento della compilazione. Non è più necessario a meno che la lunghezza dell’array non cambi (e, in tal caso, probabilmente vorrai che venga ricalcolato con ogni iterazione comunque).
Grazie a diversi sviluppatori che lo hanno sottolineato. Se vuoi saperne di più, dai un’occhiata a questa domanda su StackOverflow .
Per coloro che sono interessati, c’era un certo incentivo alla scrittura for (let i = 0, len = array.length; i < len; i++)
piuttosto che for (let i = 0; i < array.length; i++)
. Questo non è più il caso!