Campi privati in Javascript
Con la traduzione di quest’ultimo pezzo penso di concludere la serie di traduzioni dei testi presenti sul sito di Douglas Crockford. Si è trattato di pezzi interessanti che hanno coperto aspetti del linguaggio Javascript che solitamente misconosciuti. Almeno per me lo erano, e non potrò mai ringraziare abbastanza l’autore per averli scritti ed avermi concesso di pubblicarne la traduzione.
In questo post Crockford illustra la possibilità di utilizzare le chiusure per dotare gli oggetti Javascript di membri privati. Al solito non si limita a riportare un pattern di programmazione ma si sofferma sulla sua implementazione e sui meccanismi che gli stanno dietro.
Buona lettura.
Campi privati in Javascript
Titolo originale: Private members in JavaScript
Douglas Crockford (www.crockford.com)
Javascript è il linguaggio di programmazione più incompreso del mondo. Alcuni credono che non supporti l’incapsulamento delle informazioni perché gli oggetti non possono avere campi e metodi privati. Si tratta di un fraintendimento. Gli oggetti Javascript possono averer membri privati. Di seguito spiegherò come questo sia possibile.
Oggetti
Javascript è basato sugli oggetti. Gli Array sono oggetti. Le Funzioni sono oggetti. Gli Oggetti sono oggetti. In definitiva, cosa sono gli oggetti? Un Oggetto è una collezione di coppie nome-valore. I nomi sono stringhe, ed i valori possono essere stringhe, numeri, valori booleani o oggetti (inclusi vettori e funzioni). Gli oggetti sono solitamente implementati come tabelle hash in modo che i campi possano essere indirizzati rapidamente.
Se il valore è una funzione allora questa viene chiamata metodo. Quando viene invocato il metodo di un oggetto la variabile this referenzia l’oggetto. In questo modo, tramite this, il metodo potrà accedere alle variabili d’istanza.
Un Oggetto può essere creato da un costruttore, che è una funzione che inizializza oggetti. I construttori forniscono agli oggetti caratteristiche che in altri linguaggi sono conferite tramite classi, inclusi variabili statiche e metodi.
Public
I membri di un oggetto sono tutti metodi pubblici. Qualunque funzione può accedere, modificare o cancellare questi membri, o aggiungerne di nuovi. Ci sono due modi di aggiungere un membro ad un nuovo oggetto:
Nel costruttore
Questa tecnica viene solitamente usata per inizializzare le variabili pubbliche di istanza. La variabile this viene usata per aggiungere membri all’oggetto
function Container(param) {
this.member = param;
}
In questo modo, se costruiamo un nuovo oggetto
var myContainer = new Container('abc');
allora myContainer.member conterrà 'abc'.
Nel Prototipo
Questa tecnica si usa, solitamente, per aggiungere metodi pubblici. Quando un membro viene cercato inutilmente in un oggetto, viene usato il metodo del prototipo del costruttore dell’oggetto. L’ereditarietà viene garantita per delega. Questo sistema risparmia anche memoria. Per aggiungere un metodo a tutti gli oggetti creati tramite un costruttore, aggiungiamo una funzione al prototipo del costruttore (prototype):
Container.prototype.stamp = function (string) {
return this.member + string;
}
In questo modo possiamo invocare il metodo
myContainer.stamp('def');
che stampa 'abcdef'.
Membri Privati
I membri privati sono creati dai costruttori. I parametri e le variabili locali (dichiarate con var) diventano membri privati.
function Container(param) {
this.member = param;
var secret = 3;
var that = this;
}
Questo costruttore crea tre variabili d’istanza private: param, secret e that. Queste vengono aggiunte all’oggetto ma non sono accessibili dall’esterno, e neanche dai metodi pubblici dell’oggetto. Sono accessibili solamente dai metodi privati. I metodi privati di un oggetto sono le funzioni nidificate all’interno del costruttore.
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
}
Il metodo privato dec esamina la variabile d’istanza secret. Se questa è maggiore di zero, la decrementa e restituisce true. In caso contrario restituisce false. Questo metodo può essere usato per creare oggetti utilizzabili solamente tre volte.
Per convenzione, creiamo un membro privato that. Questo viene utilizzato per permettere ai metodi privati di accedere all’oggetto che li contiene. Si tratta di uno stratagemma utile ad evitare un errore delle specifiche del linguaggio ECMAScript che attribuisce a this un valore sbagliato per le funzioni nidificate.
I metodo privati non possono essere chiamati dai metodi pubblici. Per rendere i metodi privati utili abbiamo bisogno di introdurre i metodi privilegiati.
Metodi Privilegiati
Un metodo privilegiato può accedere alle variabili private ed ai metodi, ed è visibile all’esterno, come ai metodi pubblici. E possibile eliminare o rimpiazzare un metodo privilegiato ma non è possibile modificarlo, o forzarlo a rivelare i propri segreti.
I metodi privilegiati sono assegnati con this all’interno del costruttore.
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
this.service = function () {
if (dec()) {
return that.member;
} else {
return null;
}
};
}
service è un metodo privilegiato. MyContainer.service() restituirà 'abc' le prime tre volte che viene invocato. Dalla quarta volta in poi, restituirà null. Quando invocato, service chiama il metodo privato dec che, a sua volta, accede alla variabile privata secret. Il metodo service è raggiungibile dagli altri oggetti ed agli altri metodi ma non permette di accedere direttamente ai metodi privati.
Chiusure
Questo pattern di metodi pubblici, privati e privilegiati, è possibile perché Javascript supporta le chiusure. Questo significa che una funzione annidata ha sempre accesso alle variabili ed ai parametri della funzione che la incapsula anche se l’altra funzione ha terminato la propria esecuzione. Si tratta di una caratteristica del linguaggio estremamente potente. Attualmente non ci sono libri che si occupino di programmazione Javascript che mostrano come sfruttarla. Parecchi non la nominano nemmeno.
I membri privati e privilegiati possono essere creati solamente quando un oggetto viene creato. I metodi pubblici possono essere aggiunti in qualunque momento.
Pattern
Public
function Constructor(…) {
this.membername = value;
}
Constructor.prototype.membername = value;
Private
function Constructor(…) {
var that = this;
var membername = value;
function membername(…) {…}
}
Note: The function statement
function membername(…) {…}
is shorthand for
var membername = function membername(…) {…};
Privileged
function Constructor(…) {
this.membername = function (…) {…};
}
—
Copyright 2001 Douglas Crockford. All Rights Reserved Wrrrldwide.

REFUSI: (è diventato quasi un mestiere…)
cancellari = cancellareconstruttore = costruttoreinizializare = inizializzareaggiungere aggiungere un metodo a tuttu = aggiungere un metodo a tuttiMy 2 cents..
Eineki edit
Corretti gli errori, che ho per questo depennato dalla lista, grazie per l’impegno
Daniele
dicembre 15, 2009 alle 22:21 pm