Scalabilità delle applicazioni Javascript

di: Marco Solazzi     08 Novembre 2010

Chiunque abbia sviluppato una piccola applicazione o una semplice interattività in JavaScript si sarà imbattuto almeno un volta in un metodo che prevedesse una funzione di callback. Strutture di questo tipo si incontrano molto spesso utilizzando librerie come jQuery:

$('a').click(function () {
    //qui il codice della callback
});

Molti sviluppatori non trovano alcun problema nell'utilizzare questo pattern di programmazione nel loro codice e molto spesso la causa principale di tale comportamento è la poca importanza attribuita alla progettazione di applicazioni JavaScript e l'utilizzo del linguaggio come surrogato di Flash o panacea alle limitazioni del DOM.

In effetti, sebbene il codice in questione sia del tutto legittimo, esso introduce delle limitazioni architetturali che precludono la modularità e scalabilità dell'applicazione.
La più pesante conseguenza di tutto ciò è che spesso ci si trova a riscrivere intere porzioni di codice per assecondare un'unica modifica dell'applicazione.

Il problema delle funzioni anonime

Le limitazioni nell'uso di callback derivano principalmente dal fatto che troppo spesso vi si associano funzioni anonime, una caratteristica potente ma pericolosa del linguaggio JavaScript:

el.onclick = function () {
    //questa è una funzione anonima
};

var miaFunzione = function () {
    // anche questa è una funzione anonima
};

Queste funzioni non sono identificabili in nessun modo da altre parti dell'applicazione e quindi servono un unico scopo e molto spesso si accompagnano a codice duplicato:

el.onclick = function () {
    var box = document.getElementById('box');
    box.style.color = '#F00';
};

el2.onclick = function () {
    // codice duplicato
    var box = document.getElementById('box');
    box.style.color = '#F00';
};

Un primo passo per ottimizzare il codice precedente è quello di instanziare una funzione assegnandole un nome:

function cambiaColore () {
    var box = document.getElementById('box');
    box.style.color = '#F00';
}

el.onclick = cambiaColore;

el2.onclick = cambiaColore;

Si capisce subito che non solo si diminuisce il peso del codice, ma si rende tutta l'applicazione più facilmente aggiornabile.

Un altro vantaggio non indifferente è che sarà più facile fare riferimento alla funzione di callback in fase di debug.

Il più vistoso effetto collaterale di questo approccio è che comporta la definizione di molti oggetti globali, con il rischio che altri script possano sovrascrivere le funzioni definite precedentemente.

Per ovviare a questo problema si può utilizzare una funzione self-executing attraverso la quale contenere le funzioni in un contesto (scope) privato:

(function () {
    function cambiaColore () {
        var box = document.getElementById('box');
        box.style.color = '#F00';
    }

    function altraFunzione () {
        //codice
    }

    el.onclick = cambiaColore;

    el2.onclick = altraFunzione;
})();

oppure usare un oggetto come namespace generico:

var mieFunzioni = {
    cambiaColore : function  () {
        var box = document.getElementById('box');
        box.style.color = '#F00';
    },
    altraFunzione : function  () {
        //codice
    }
};

el.onclick = mieFunzioni.cambiaColore;

el2.onclick = mieFunzioni.altraFunzione;

In quest'ultimo caso il vantaggio è che le funzioni definite come metodi dell'oggetto mieFunzioni sono raggiungibili dal contesto globale e quindi riutilizzabili in altre parti dell'applicazione.

Guide JavaScript

Guida Node.js

Il framework che permette di per usare V8, l'interprete JavaScript...

Canvas, guida ai framework

Canvas, tra gli elementi di HTML5 è forse quello di maggior impatto....

Guida jQuery UI

Creare siti ricchi e dinamici con jQuery UI, il progetto ufficiale...

Altre guide

Newsletter @JavaScript

Ogni martedì, direttamente nella tua e-mail: guide, articoli, script, novità e approfondimenti tecnici su JavaScript.

Iscriviti alla newsletter

Altre newsletter

Corsi in aula

Corso Webmaster base

18 Giugno 2012 a Milano
Disponibilità: 6 Posti

Corso Google AdWords Base

25 Giugno 2012 a Milano
Disponibilità: 7 Posti

Corso JQuery e Ajax per Webmaster

03 Luglio 2012 a Milano
Disponibilità: 7 Posti

Corso Google AdWords Base

05 Giugno 2012 a Roma
Disponibilità: 7 Posti

Corso Webmaster base

11 Giugno 2012 a Roma
Disponibilità: 7 Posti