JavaScript è debolmente tipizzato
Essere debolmente tipizzato è la prima e più importante differenza rispetto al linguaggio Java.
JavaScript non dispone dei tipi canonici a cui siete abituati in Java, ma di una caratteristica che richiama il comportamento dei wrapper che conoscete. Ad esempio il valore 1
è un'istanza dell'oggetto Number
ed è un numero intero.
Sareste portati a pensare che esistano anche oggetti come Double
e Float
per i numeri in virgola mobile. Non è così: esiste solo Number
ed è l'interprete JavaScript a considerare le variabili in modo dinamico a seconda del loro valore.
Di seguito alcune variabili con diversi tipi di dati. Notate l'assenza della dichiarazione di tipo.
let numInt = 10; // intero
typeof numInt; // Number
let numDec = 9.52; // decimale
typeof numDec; // Number
let strSingleQuotes = 'Hello'; // stringa
typeof strSingleQuotes; // String
let strDoubleQuotes = "Hello";
typeof strDoubleQuotes; // String
typeof foo; // undefined
let obj = {
bar: 'ok',
method: function() {
return this.bar;
}
};
typeof obj; // Object (oggetto letterale);
let fn = function() {
console.log('fn()');
};
typeof fn; // Function
let arr = [1, 2, 'a', 'b', {a: 1}]; // array
typeof arr; // Object
let n = null; // valore null
typeof n; // Object
L'operatore typeof
restituisce il tipo di dati di una variabile, ma come dimostrano gli ultimi due esempi ha un'affidabilità limitata. Avrete anche notato che gli array in
JavaScript possono contenere qualsiasi tipo di dati e la loro dimensione è variabile come le collezioni in Java. Rispondendo alle vostra domanda circa l'esito sconcertante delle ultime
due chiamate a typeof
, in JavaScript si usano le seguenti soluzioni:
let arr = [1, 2, 'a', 'b', {a: 1}]; // array
Array.isArray(arr); // true
let n = null; // valore null
(n === null); // true, notate l'operatore di identità, preferito in JavaScript
JavaScript ha un supporto parziale all'OOP
JavaScript attualmente non dispone degli operatori di visibilità, delle interfacce, dei tipi astratti e più in generale di tutte quelle feature avanzate a cui siete abituati in Java. Allo stato attualmente JavaScript implementa una versione basica delle classi con supporto al solo costruttore e ai metodi statici, ma per lo più in JavaScript non esistono di fatto le classi come le si intendono in Java.
Infatti dato che JavaScript supporta le funzioni, per lo più gli oggetti vengono creati utilizzando le funzioni come costruttori e sfruttando la proprietà prototype
per l'ereditarietà e l'estensione.
Ne consegue che in JavaScript il paradigma funzionale è molto diffuso e negli ultimi anni grazie al successo di librerie come Underscore e Lodash si è affermato con successo. In definitiva si può dire che JavaScript, pur essendo un linguaggio basato sugli oggetti, non ha nel paradigma OOP l'unico modo di strutturare il codice.
Concisione: pregio o difetto?
Seguendo il dibattito sugli stream e le funzioni lambda in Java, possiamo dire che in JavaScript la concisione è sempre stata al centro di varie discussioni vertenti sul fatto che grazie alla concatenazione si ottiene un codice più compatto ma anche più difficile da leggere soprattutto per chi è agli inizi.
Facciamo un esempio:
'use strict'; // Abilita la modalità rigorosa
const uniqueId = function(len) {
return 'abcdefghijklmnopqrstuvxyz0123456789'.split('').sort(() => { return Math.random() * 0.5; }).join('').substring(0, len);
};
Per i principianti una funzione del genere è quasi indecifrabile. Analizzando la catena dei metodi si può dedurre che viene generata una stringa alfanumerica casuale di lunghezza len
, ma il punto è che a distanza di tempo tornare su un'implementazione scritta in questo modo può risultare arduo.
JavaScript sa essere conciso, ma questa caratteristica diventa un difetto se ne si abusa.
Internazionalizzazione e localizzazione
Nonostante gli enormi passi avanti compiuti da JavaScript negli ultimi anni nel campo dell'internazionalizzazione e della localizzazione, siamo ancora ben lontani dal livello a cui siete abituati in Java.
Ciò diventa particolarmente evidente se si usa JavaScript sul server con NodeJS. A differenza di PHP, Node non dispone di un set di locales all'atto dell'installazione, ma ripiega in modo predefinito sul locale EN-US. Di conseguenza l'espressione:
console.log(new Date().toLocaleDateString());
produrrà:
13/10/2018
che risulta corretto nel formato italiano su un SO e un browser in Italiano, ma se proviamo a cambiare locale sul server non otterremo i risultati sperati a meno di non specificare un locale diverso all'atto della compilazione di Node (questo non è possibile se lo si installa tramite pacchetto della distribuzione).
Per ovviare al problema la soluzione consiste nell'utilizzare moduli che contengano già un set di locales per la formattazione delle stringhe, dei valori monetari e delle date.