In JavaScript, i valori possono essere di tipi diversi. Cambiare il tipo di una variabile si può fare con una conversione di tipo esplicita. Oltre a questo, JavaScript esegue anche una coercizione di tipo (conversione di tipo implicita) quando il contesto lo richiede.
JavaScript non ha un costrutto per eseguire il cast verso un tipo (diverso) come molti altri linguaggi, ma in alternativa si possono usare alcuni helper integrati.
In particolare, gli oggetti globali Boolean, Number e String possono essere usati come funzioni per convertire un valore nel tipo corrispondente.
Con Boolean(value) puoi convertire qualsiasi valore in un booleano.
Come funziona?
Esiste un insieme fisso di valori, i cosiddetti valori falsy, che vengono convertiti in false.
In particolare, false, 0, la stringa vuota, null, undefined e NaN sono falsy.
L'articolo di MDN su «Falsy» mostra l'elenco completo.
Per tutti gli altri valori, Boolean restituisce true.
Questi valori sono chiamati truthy.
Boolean(-1);
// => true
Boolean(0);
// => false
Boolean(' ');
// => true
Boolean('');
// => false
Nota che, in base alle regole descritte, '0', 'false', [] e {} sono truthy in JavaScript.
Number(value) può essere usato per convertire un valore in un numero.
Gli spazi all'inizio e alla fine di una stringa vengono ignorati e una stringa vuota viene convertita in 0.
Se provi a convertire un valore non primitivo o una stringa che non rappresenta un numero, non verrà generato alcun errore.
Invece, il risultato è NaN (Not-A-Number).
Number(' -12.34 ');
// => -12.34
Number('1,2');
// => NaN
Number('1 2');
// => NaN
Number('');
// => 0
Number('10e3');
// => 10000
Number({ key: '123' });
// => NaN
Qui sotto puoi vedere cosa restituisce Number per altri valori primitivi.
Number(true);
// => 1
Number(false);
// => 0
Number(null);
// => 0
Number(undefined);
// => NaN
Nota che, a differenza dell'ultimo esempio, Number() chiamato senza argomenti è definito per restituire 0.
JavaScript fornisce anche le funzioni parseInt e parseFloat.
Applicano regole più permissive su quali stringhe possono essere convertite in un numero.
Per questo motivo, Number dovrebbe essere preferito come funzione di conversione per evitare risultati inattesi.
parseInt('123a45');
// => 123
Number('123a45');
// => NaN
Con String(value) puoi convertire un valore in una stringa.
Il risultato è quello che ti aspetteresti per i valori primitivi.
String(12.34);
// => '12.34'
String(false);
// => 'false'
String(null);
// => 'null'
String(undefined);
// => 'undefined'
Per gli array, la funzione String applica la conversione in stringa a ogni elemento e unisce i risultati con una virgola.
Puoi anche applicare tu stesso il metodo join, ad esempio per personalizzare il separatore.
Tuttavia, in questi casi null e undefined verranno convertiti in una stringa vuota.
String([42, null, true, 'abc']);
// => '42,,true,abc'
Per gli oggetti, per impostazione predefinita String restituisce un testo poco utile.
String({ key: 'value' });
// => '[object Object]'
Puoi personalizzare il comportamento di conversione, ad esempio fornendo un metodo toString.
La sezione «Conversione da oggetto a primitivo»custom-conversion su javascript.info spiega i dettagli.
Un altro modo comune per ottenere una rappresentazione in stringa migliore per oggetti e array è usare la codifica JSON.
Puoi convertire in una stringa con JSON.stringify e di nuovo in un oggetto o array con JSON.parse.
const obj = {
name: 'Gilda Guerra',
address: {
city: 'Goiânia',
},
};
JSON.stringify(obj);
// => '{"name":"Gilda Guerra","address":{"city":"Goiânia"}}'
In alcuni contesti, JavaScript converte automaticamente un valore in un altro tipo di dato prima di valutare un'istruzione. Questa conversione implicita è chiamata coercizione di tipo.
Quando un valore viene usato in un contesto booleano, JavaScript applica le stesse regole della funzione Boolean per convertirlo implicitamente.
Quando la condizione di un'istruzione if non è un booleano, viene applicata la coercizione per determinare se la condizione è soddisfatta o meno.
Lo stesso vale per il primo operando dell'operatore ternario ?.
const num = 0;
if (num) {
// this block is NOT executed because 0 is falsy
}
const name = 'Jin';
name ? 'name was provided' : 'no name provided';
// => 'name was provided'
Anche l'operando dell'operatore logico NOT ! viene convertito in booleano prima che venga applicata l'operazione NOT.
const name = '';
!name;
// => true
Una conseguenza del comportamento descritto è che !!value ha lo stesso effetto di Boolean(value).
Tuttavia, per leggibilità dovresti usare Boolean.
JavaScript applica la coercizione anche agli operandi degli operatori logici AND (&&) e OR (||).
Ma tieni presente che il risultato dell'espressione non è necessariamente un booleano.
Restituisce uno degli operandi originali (vedi MDN sugli operatori logici).
null || 'hello';
// => 'hello'
Se l'operatore di addizione + viene usato con valori primitivi e un operando è una stringa, anche l'altro verrà convertito in una stringa.
La logica di conversione è la stessa dell'uso della funzione String.
In seguito, le due stringhe vengono concatenate.
let name;
'hello ' + name;
// => 'hello undefined'
La stessa conversione implicita avviene per i valori non stringa incorporati nelle stringhe interpolate.
const degrees = 23;
`It is ${degrees} °C`;
// => 'Is is 23 °C.';
Molti operatori convertono gli operandi in numeri (se necessario) secondo la logica della funzione Number spiegata sopra.
+ (se non è coinvolta alcuna stringa), -, *, /, %, **
+, -
>, >=, <, <=
|, &, ^, ~
Fai riferimento all'elenco degli operatori di MDN per maggiori dettagli su ciascuno di questi operatori.
Quando un operando potrebbe essere una stringa, è meglio convertirlo sempre esplicitamente con la funzione Number per evitare errori.
'1' + '2';
// => '12'
// addition operator in string context as explained above
Number('1') + Number('2');
// => 3
A volte vedrai usare l'operatore più unario per convertire una stringa in un numero.
Questo non è consigliato, perché è molto più difficile da leggere rispetto alla chiamata esplicita a Number.
const value = '42';
+value;
// => 42
Number(value);
// => 42
Anche l'uso degli operatori di uguaglianza e disuguaglianza debole ==/!= comporta spesso una conversione implicita in un numero.
Tuttavia, la logica esatta di questi operatori è piuttosto complicata (vedi MDN sull'uguaglianza debole).
I risultati sono difficili da prevedere e a volte non sono quelli che ti aspetteresti.
Usa invece gli operatori di uguaglianza/disuguaglianza stretta ===/!== per evitare queste conversioni implicite.