Pillole di Javascript: i wrapper dei tipi primitivi

Collezione di matrioske in esposizione in un negozio di Londra

Per i tipi primitivi string, number e boolean esistono i relativi oggetti wrapper: String, Number e Boolean. E’ possibile instanziare uno di questi oggetti chiamando il suo costruttore. Se al costruttore non viene passato nessun valore, il wrapper viene inizializzato con un valore di default (rispettivamente stringa vuota, intero 0 e false). Se si passa un valore, di qualsiasi tipo, viene convertito al tipo rappresentato dal wrapper e usato come valore del wrapper. Alcuni esempi:

// tipi primitivi espressi con valori letterali
var n = 42;
var s = "hello";
var b = false;

// wrapper inizializzati con variabili primitive
var N = new Number(n);
var S = new String(s);
var B = new Boolean(b);

// wrapper inizializzati con valori letterali
var N2 = new Number(123);
var S2 = new String("Hello World");
var B2 = new Boolean(true);

// wrapper inizializzati con valori di tipo diverso dal wrapper
var N3 = new Number("abc") // viene inizializzato a "NaN"
var S3 = new String(true) // viene inizializzato con la stringa "true"
var B3 = new Boolean({}) // un oggetto è considerato true per specifica

I wrapper sono utili perché contengono dei metodi per operare sui valori che contengono. Ad esempio il wrapper String contiene, tra gli altri, i metodi substring e split. Invece i valori primitivi, non essendo oggetti, non possono avere metodi. Tuttavia Javascript offre una sintassi che permette di chiamare i metodi del wrapper anche sul suo rispettivo tipo primitivo. Ad esempio è possibile scrivere:

"hello, world".split(",");

Questa sintassi è supportata perché viene tradotta dal compilatore nell’istruzione così formata:

new String("hello, world").split(",");

viene quindi creato un wrapper String, inizializzato con il letterale, su cui viene invocato il metodo. Terminata l’esecuzione del metodo il wrapper viene perso perché non referenziato, e verrà quindi distrutto dal garbage collector. Il valore primitivo può essere anche in una variabile:

var s = "hello, world";
s.split(",") // tradotta così: new String(s).split(",")

Lo stesso meccanismo vale anche per i tipi numerici e booleani. L’unica nota da fare è che i letterali numerici necessitano delle parentesi tonde, altrimenti la sintassi è considerata errata:

42.toExponential(); // errore di sintassi
(42).toExponential(); // sintassi corretta
new Number(42).toExponential(); // stessa istruzione ma per esteso
Precedente Pillole di Javascript: tipi di dato Successivo Pillole di Javascript: numeri e aritmetica