2016-06-15 12 views
6

La funzione scoping offre l'esclusiva privacy in JavaScript.Privacy in JavaScript

Quindi la canonica:

function Ctor(dep1, dep2) { 
    this._dep1 = dep1; 
    this._dep2 = dep2; 
} 

Ctor.prototype.foo = function() { 
    // use this._dep1/2... 
} 

... è problematica in quanto non offre alcuna incapsulamento per le dipendenze iniettati.

Un'alternativa (seppur leggermente diverso in termini di posizione di foo) che offre reale incapsulamento potrebbe essere:

function factory(dep1, dep2) { 
    return { 
    foo: partial(foo, dep1, dep2), // or use bind (partial could be a library fn for partial application) 
    }; 
} 

function foo(dep1, dep2) { 
    // use dep1/2 
} 

ma raramente vedere questo modello. C'è una buona ragione per non usare quest'ultimo?

+1

in una certa misura, il supporto per Symbol le proprietà miglioreranno le cose, come sarà possibile t o creare chiavi di proprietà che non siano in conflitto con altre chiavi. Tuttavia, non sono ancora completamente "privati". – Pointy

+1

Vota per chiudi - perché ?! – Ben

risposta

3

Già dichiari i vantaggi del secondo modello. Gli svantaggi sono:

  • si deve o metodi di gruppo di visibilità (anche se il metodo privato è intimamente legata con una pubblica, ma a malapena legato ad altri metodi privati), o ripetere tutti i metodi pubblici della letterale oggetto (che non funziona bene con jsdoc).

  • il codice introduce un oggetto funzione separata per ogni istanza della classe, che sacrifica alcune prestazioni (questo di solito non importa, ma a volte potrebbe)

  • a differenza di modificatori private in molti linguaggi di programmazione, questo incapsulamento non può essere aggirato, anche se applicato erroneamente e so davvero quello che sto facendo (storicamente, JavaScript è stato un ambiente dove tutto è permesso, e molti attribuiscono il suo successo a questa estensibilità)

+0

"il codice introduce un oggetto funzione separato per ogni istanza della classe" - anche se il codice usa 'bind' direttamente ad es. 'foo: foo.bind (null, dep1, dep2)'? – Ben

+0

Sì, l'ho appena testato su Chrome: 'foo.bind (null, 1, 2) === foo.bind (null, 1, 2)' restituisce 'false'. – meriton

+0

Ah si hai ragione. Grazie per la conferma. Anche https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind – Ben

3

Semplice: perché?

"Privacy" è terribilmente sopravvalutato. Non nasconde nulla a nessuno che lo voglia davvero. Avere membri "protetti" o "privati" è puramente a beneficio del programmatore, in particolare per indicare come deve essere usato un particolare membro (questo qui è un'API pubblica, questo qui non è così per favore non toccare a meno che tu non sappia cosa fa). È tutto. Una convenzione di denominazione come l'inizio di underscore è perfettamente sufficiente per implementarlo. Se il nome di un membro inizia con un carattere di sottolineatura, non toccarlo, a meno che tu non sappia cosa stai facendo.

Non c'è alcun bisogno intrinseco di piegarsi all'indietro oltre.

+0

In risposta alla tua domanda: "perché con' _foo', quando si lavora in una base di codice condivisa, non si può essere sicuri che non venga usato perché il nome è 'solo un nome' ". La fiducia è significativamente aumentata nel secondo, migliorando gli aspetti non funzionali del codice. – Ben

+1

Se non hai fiducia nei tuoi colleghi, rendere privati ​​i membri privati ​​non ti aiuterà. Questo è un problema di comunicazione e/o revisione tra programmatori e non un problema tecnico da risolvere. Ci sono ancora molte cose che i programmatori non fidati sono in grado di rovinare rispetto all'accesso ai membri privati. – deceze

+0

Ci sono molti problemi nello sviluppo del software. Ne citi alcuni. Ciò significa che non dovremmo cercare di mitigare il rischio rappresentato da questi problemi? – Ben

Problemi correlati