Penso di aver frainteso il funzionamento dell'ereditarietà del prototipo Javascript. Nello specifico, le variabili interne dei prototipi sembrano essere condivise tra più sotto-oggetti diversi. È facile illustrare con codice:Variabili private nei prototipi ereditati
var A = function()
{
var internal = 0;
this.increment = function()
{
return ++internal;
};
};
var B = function() {};
// inherit from A
B.prototype = new A;
x = new B;
y = new B;
$('#hello').text(x.increment() + " - " + y.increment());
Questo fornisce in uscita 1 - 2
(test su JSBin), mentre aspettavo il risultato sia 1 - 1
, dato che volevo due oggetti separati.
Come posso essere sicuro che l'oggetto A
non sia un oggetto condiviso tra più istanze di B
?
Aggiornamento: This article mette in evidenza alcuni dei problemi:
Il problema è che il campo di applicazione ogni approccio utilizza per creare una variabile privata, che funziona bene, è anche la chiusura, in azione, che i risultati in se si modifica una variabile privata per un'istanza di oggetto, viene modificata per tutti. Cioè è più simile a una proprietà statica privata, che a una variabile privata effettiva.
Quindi, se si desidera avere qualcosa di privato, più come una costante non pubblica, uno qualsiasi degli approcci precedenti è buono, ma non per le vere variabili private. Le variabili private funzionano davvero bene solo con gli oggetti Singleton in JavaScript.
Soluzione: Come per la risposta di BGerrissen, cambiando la dichiarazione di B
e lasciando del prototipo funziona come previsto:
var B = function() { A.apply(this, arguments); };
Ma il punto qui è che la funzionalità appartiene a 'A', ed è condivisa tra più sub "classi"(' B', 'C' e 'D'). Non c'è possibilità per variabili private non statiche nelle superclassi in Javascript? –
Un modo comune per indicare le intenzioni "private" (ovvero i programmatori di avvisi che qualcosa di speciale sta accadendo con una proprietà) consiste nell'usare il carattere di sottolineatura come prefisso al nome della proprietà (ad esempio obj._privateMember). Sebbene questo funzioni con l'ereditarietà di stringhe e numeri, inizia a diventare più complesso quando si utilizzano Oggetti e Matrici come proprietà. – BGerrissen
Non sono chiaro esattamente cosa stai chiedendo. Vuoi che una variabile definita all'interno della funzione 'A' sia disponibile per i metodi di' B', 'C' e' D', ma da nessun'altra parte? Cerca di non pensare a cose in JavaScript in termini di funzionalità di altri linguaggi (come Java o C#). JavaScript semplicemente non ha classi. Ha oggetti che ereditano le proprietà da altri oggetti tramite una catena di prototipi. –