Diary

Javascript Coercion - Part. 1

Andrea - 2 weeks ago (Nov 6, 2019)

Ed eccomi qua, anche oggi, caro diario a prendere appunti di programmazione.

Oggi, sto affrontando un problema di per se concettualmente molto semplice. Sto esercitando la programmazione con Javascript e voglio approfondire un tema controverso ma che deve essere studiato a fondo, caso per caso, per poter essere compreso nella sua totalità.

Oggi voglio fare un po' di conversioni. Mi sono sempre chiesto come funziona il meccanismo interno di JS quando deve usare un valore come numero o come testo e soprattutto non ho mai ben chiaro il motivo per cui


var a = 4;
var b = "foo";

console.log(a + b); // 4foo

// oppure
console.log(a < b); // false
console.log(a > b); // false
console.log(a == b); // false

Premessa sui tipi

E' necessario fare una breve premessa per preparare il campo ai concetti che andrò ad esprimere nei capitoli successivi. Cosa sono i tipi di variabile? Quanti sono i tipi di variabile in JS? Possiamo parlare di tipi di variabile o si tratta di tipi di valori? ..quante domande!!

Javascript è un linguaggio di programmazione decisamente strano nei confronti dei tipi di variabile.

Infatti, in JS abbiamo fondamentalmente 6 tipi a disposizione (7 se contiamo anche null separatamente). La particolarità, in questo caso, sta nel fatto che questi 6 tipi non sono legati alla variabile che andremmo ad utilizzare ma sono legati al valore che viene dato a quella stessa variabile.

Ogni variabile in JS può contenere un qualsiasi tipo di variabile in qualsiasi momento del programma (a.k.a. dinamic typing).

Qui di seguito, riporto 3 esempi di assegnazione di 3 diversi tipi di valore alla stessa variabile a.


var a;

a = "Hello"; // string
a = 35; // number

// ...
a = true; // boolean

Questa logica va contro ai più comuni dogmi dei linguaggi fortemente tipizzati (a.k.a. type enforcement) dove ad ogni variabile viene assegnato un tipo di dato e quel tipo di dato deve rimanere invariato nel corso di tutto il codice del programma.

Da questo strano comportamento derivano tutta una serie di domande sul comportamento del linguaggio durante la stesura del codice e la manipolazione delle variabili.

Quale sarà il comportamento del linguaggio nei casi simili a quelli che vi presento qui sotto?


var a = "35"; // string
var b = 3; // number
var c = 35; // number
var d = "foo"; // string

console.log(a * b);
console.log(a == c);
console.log(a === c);
console.log(b + d);

Nel prossimo capitolo cercherò di svelare il mistero. Per il momento mi limito ad elencare per completezza i 6 tipi disponibili su JS che possiamo anche chiamare primitives.

  • string con la relativa funzione String
  • number con la relativa funzione Number
  • boolean con la relativa funzione Boolean
  • null e undefined
  • object
  • symbol un nuovo tipo introdotto in ES6

Conversione tra tipi

Ipotiziamo di voler lavorare con dei numeri number e ad un certo punto abbiamo bisogno di visualizzare il valore a video per un debug del codice; Per poterlo fare abbiamo bisogno di convertire quel valore in una stringa di testo string che potrà essere letta facilemente sullo schermo.

Allo stesso modo, se un utente inserisce una serie di numeri all'interno di un form ed invia i dati quei valori sono passati come stringa string. Se poi dobbiamo usare quella stringa di numeri per eseguire una serie di calcoli matematici dovremmo convertirli, nel tipo corretto number ed eseguire i calcoli necessari.

Tutte queste conversioni, automatiche o volute, in Javascript vengono chiamate coercion; In italiano potremmo tradurlo, semplificando, in coercizzare: forzare una cosa a diventare un altra cosa.

Esistono vari modi, in Javascript, per effettuare la conversione dei tipi ma principalmente questa, avviene in 2 modi: modo implicito e modo esplicito.

Conversione esplicita

Per convertire un valore in modo esplicito basta semplicemente assegnare il tipo di dato primitivo, al valore:


var a = "42";
var b = Number(a);

console.log(a); // "42" - string
console.log(b); // 42 - number

Usando la funzione built-in Number(..), come mostrato sopra, effettuo una conversione esplicita dal tipo string al tipo number. Niente di sovrannaturale, la conversione è visibile direttamente nel codice scritto ed è gestibile dal programmatore senza dare modo di commettere errori.

Il bello del discorso avviene quando Javascript si prende qualche "licenza poetica" (se cosi le possiamo chiamare) ed effettua le conversioni dei dati per conto suo, in modo implicito. Questo comportamento, se non viene bene compreso, si trasforma in un problema.

Ok, nessun problema, stiamo calmi, la coversione implicita è un argomento che si può imparare, anzi, tutti gli aspiranti programmatori devono impararlo a fondo per apprezzarne le potenzialità e gli usi. Nel prossimo capito.

Conversione implicita

Questo tipo di conversione probabilmente è quello che provoca maggiori effetti collaterali al nostro programma se non abbiamo compreso a fondo il suo meccanismo. Online si vedono spesso dibattiti su questo argomento proprio per il fatto che in JS la conversione dei tipi di valore molto spesso provoca degli effetti a sorpresa abbastanza particolari. Vediamo se riesco a fare un po' di chiarezza sul tema.

Attendibile o Inaffidabile

Per introdurre questo argomento è necessario fare una panoramica dei valori che in JS si possono definire veri in contrapposizione con i valori che invece saranno sicuramente falsi. Questa grande distinzione serve come base di partenza per definire come JS esegue una comparazione tra due valori quando questi vengono implicitamente coercizzati a boolean.

La lista da ricordare a memoria in questo caso è quella dei valori falsi:

  • "" (empty string) stringa vuota
  • 0, -0, NaN (numero non valido)
  • null, undefined
  • false

Tutti gli altri valori si possono considerare come veri, alcuni esempi:

  • "ciao"
  • 42
  • true
  • [ ], [ 1, "2", 3 ] (arrays)
  • { }, { a: 42 } (objects)
  • function foo() { .. } (functions)

Una volta che abbiamo imparato questo semplice schema siamo pronti per sapere tutto quello che c'è da sapere sulla conversione implicita dei valori in Javascript.

Cavoli, questo taccuino per gli appunti è davvero piccolo. Ormai sono a fondo pagina credo proprio che dovrò scrivere i prossimi capitoli su un foglio nuovo.