JavaScript non ha gli array associativi

English version

Questo post riguarda uno dei più comuni equivoci di JavaScript: gli array associativi.

JavaScript supporta la sintassi degli array associativi, ma non ha realmente questa struttura dati. Sarebbe inutile, perché possiamo usare gli oggetti.

Ecco un semplice oggetto:

var movie = {
    title : '2001: A space Odissey',
    director : 'Stanley Kubrick',
    year : 1968
};

Abbiamo definito una variabile oggetto (movie) con 3 proprietà (title, director, year). Siccome le proprietà sono sempre pubbliche in JavaScript, possiamo leggerle:

alert('Title: ' + movie.title);

Inoltre JavaScript è molto dinamico, perciò possiamo anche modificare le proprietà o crearne di nuove:

movie.genre = 'sf';

Possiamo poi utilizzare la sintassi classica degli array associativi per accedere alle proprietà di un oggetto:

alert('Title: ' + movie['title']);

Può sembrare inutile… e in questo esempio lo è davvero. E’ meglio non usare questa sintassi se non è necessario. Ma possiamo utilizzarla per accedere ad una proprietà che non conosciamo a priori:

var prop = 'title';
alert('Title: ' + movie[prop]);

E’ particolarmente utile nei cicli for … in, che sono l’equivalente JavaScript dei foreach:

for (var i in movie) {
    alert(i + ': ' + movie[i]);
}

Divertitevi!

Il tag HTML <script>

Il codice JavaScript può trovarsi in file separati, oppure all’interno delle pagine HTML. Quest’ultima opzione non è consigliabile, però capita di usarla.

Qui spiego i modi migliori per includere del codice JavaScript, in entrambi i casi.

File esterni

Il codice da usare è il seguente:

<script src="percorso/nome_file.js"></script>

src è l’attributo che indica il percorso e il nome del file JavaScript da includere. E’ buona norma usare solo caratteri minuscoli nel percorso e terminare il nome del file con l’estensione .js.

Di solito i tag script contengono molti più attributi, ma non sono necessari. Ecco i motivi.

language è deprecato in favore di type, e comunque "javascript" è l’unico valore consentito dai browser. IE invece permette anche VBScript, ma il supporto a questo linguaggio dovrebbe essere considerato un bug.

type non ha alcuna utilità. L’unico valore sensato è "text/javascript", ma verrà comunque ignorato, perché il browser si fida delle intestazioni HTTP comunicate dal server, non del valore di questo attributo.

Esistono anche attributi specifici di IE, ma il supporto a questi attributi dovrebbe essere considerato un bug.

Codice embedded

Quando il codice JavaScript viene incluso in una pagina HTML, bisognerebbe usare la sintassi seguente:

<script>
    // <![CDATA[
    <cite>...codice...</cite>
    // ]]>
</script>

Grazie ai commenti (//), le stringhe <![CDATA e ]]> vengono ignorate dal motore JavaScript, evitando di generare errori. Servono invece al motore di rendering, perché indicano che al loro interno eventuali tag devono essere ignorati. Quindi caratteri come < e > potranno essere utilizzati senza paura.

Questo accorgimento, insieme a pochi altri, rende le pagine HTML5 dei documenti XML well-formed (da qui il termine informale XHTML5).

Anche in questo caso, gli inutili attributi elencati nella sezione precedente non devono essere utilizzati. Un tempo inoltre si usava circondare il codice JavaScript con i <!– commenti HTML –> ma questa tecnica è inutile (e potenzialmente dannosa) già dai tempi di… Netscape 2!

MariaDB Mode per CodeMirror

Avevo bisogno di un editor SQL scritto in JavaScript, da integrare in un tool fatto in casa che utilizzo per modificare i miei database. Ho trovato CodeMirror. Funziona molto bene ed è usato da un certo numero di progetti importanti. Il codice è rilasciato con una licenza MIT (personalmente preferirei la AGPL3, ma non importa).

CodeMirror supporta parecchi linguaggi di programmazione, e gli script relativi ai linguaggi si chiamano Mode. Ho provato la modalità MySQL, ma… beh, detto sinceramente, non mi piace. Forse sono stato sfortunato, ma le prime parole chiave che ho scritto (DELIMITER e TRUNCATE) non sono state evidenziate. Non vengono evidenziati nemmeno i numeri decimali.

Perciò ho scritto un nuovo Mode e l’ho messo su GitHub: MariaDB: https://github.com/santec/mariadb-mode-for-CodeMirror.

Prima di tutto, ho rielaborato un po’ il codice del MySQL Mode. Ora è in Strict Mode e utilizza i tipi in modo più statico. Poi ho sistemato alcuni bug minori: i commenti ‘–‘ non richiedevano uno spazio e i `backtick` potevano essere inseriti in un identificatore utilizzando ‘\’ come escape.

Poi ho aggiunto qualcosa:

  • un sacco di parole chiave di MySQL e MariaDB;
  • numeri con la virgola (ed eventualmente gli esponenti);
  • variabili (tutte le sintassi ammesse);
  • binari e hex (tutte le sintassi);
  • tutti i tipi di commenti;
  • ‘?’ (per i prepared statement).

Le limitazioni? Beh, non ha un’indentazione automatica molto intelligente, l’autocompletamento e diverse altre caratteristiche che ci starebbero bene. Però l’ho scritto soltanto per integrarlo in un tool che uso solo io. Se c’è interesse da parte di altri potrei migliorarlo, ma non credo che ci lavorerò su ancora se non sono sicuro che abbia senso.

Se usi MariaDB Mode e hai qualche commento/richiesta, fammelo sapere. Se lo migliori, per favore perdi un po’ di tempo per fare una Pull Request su GitHub.

A presto!

JavaScript NON è Java

English version

Quando dico che JavaScript non ha niente a che vedere con Java, la gente pensa che io esageri. E forse pensano che io stia conducendo una qualche strana guerra di religione. Ma cerco semplicemente di mettere in evidenza un problema. Se programmi in Lisp, e qualcuno riesce a convincerti che stai usando Java… beh, produrrai dei programmi indecenti. Per almeno due motivi: non stai usando le peculiarità di Lisp, e per quanto ti sforzi non puoi usare quelle di Java.

Ecco alcuni fatti oggettivi:

  • Java ha le classi e le interfacce, JavaScript no. Questo perché Java è Orientato agli Oggetti e JavaScript no (anche se ha il tipo object).
  • JavaScript ha il tipo function e la lazy evaluation, Java no. Questo perché JavaScript è un linguaggio funzionale e Java no.
  • In JavaScript puoi aggiungere proprietà agli oggetti a runtime, o perfino cambiare l’oggetto-padre; in Java no. Questo perché JavaScript è dinamico e Java è statico.
  • In JavaScript, non c’è motivo di usare l’operatore new. E di solito c’è un buon motivo per non usarlo. In Java non puoi nemmeno dire “Hello World” senza new.
  • In JavaScript bisognerebbe sempre avere le funzioni annidate. In Java non puoi farlo, e (se hai una vaga idea di cosa sia Java) non ti è mai passato per la mente.
  • Java ha le proprietà/metodi private e protected. In JavaScript i dati si incapsulano in un altro modo.
  • Sì, in JavaScript si può emulare l’eredità delle classi. Ma è meglio usare i prototipi. Non fingere di usare le classi, perché JavaScript non le possiede.
  • a[“b”] è un array in Java, ma è un oggetto in JavaScript.

Lo so: questo breve elenco non è una spiegazione di JavaScript. Ma spero di aver chiarito che questo linguaggio NON è simile a Java.
Allora JavaScript è un sottoinsieme di Java? No. Un linguaggio funzionale e dinamico non può essere un sottoinsieme di un linguaggio statico orientato agli oggetti. A meno di non sostenere che Haskell è un sottoinsieme di C++.
Le loro sintassi sono simili? No. La sintassi di JavaScript è uno sporco imbroglio, perché ti fa credere che stai instanziando una classe o stai accedendo a un elemento di un array associativo, quando in realtà stai facendo altro.

JavaScript è simile a Lisp, non a Java. E programmare in Java usando Lisp è una delle cose più (difficili + stupide + inutili) che un programmatore può tentare di fare. Ma non è colpa tua. E’ colpa di ECMA. Chiedegli perché ti hanno imbrogliato.

A presto!