2016-06-15 6 views
6

Scoping funkcji zapewnia jedyną prywatność w JavaScript.Prywatność w JavaScript

Więc kanoniczna:

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

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

... jest problematyczne, ponieważ oferuje nie enkapsulacji dla wstrzyknięto zależności.

Alternatywnym (aczkolwiek nieznacznie różnią się pod względem lokalizacji foo), który oferuje prawdziwy enkapsulacji może być:

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 
} 

ale rzadko zobaczyć ten wzór. Czy istnieje dobry powód, aby nie używać tego ostatniego?

+1

Do pewnego stopnia wsparcie dla Symbolu właściwości poprawią to, co będzie możliwe o utwórz klucze właściwości, które gwarantują, że nie kolidują z innymi kluczami. Jednak nadal nie są w pełni "prywatne". – Pointy

+1

Głosuj za blisko - dlaczego ?! – Ben

Odpowiedz

3

Już określasz zalety drugiego wzoru. Wadami są:

  • musisz albo metody grupowe według widoczności (nawet jeśli metoda prywatna jest ściśle związana z jednym publicznym, ale ledwo związanych z innymi metodami prywatnych), albo powtórzyć wszystkie metody publiczne w obiekcie dosłownym (co nie działa dobrze z jsdoc).

  • kod wprowadza odrębny przedmiot funkcyjnego dla każdej instancji klasy, która poświęca trochę wydajność (to zwykle nie ma znaczenia, ale czasami może)

  • przeciwieństwie do prywatnych modyfikatory w wielu językach programowania, to enkapsulacji nie da się obejść, nawet jeśli źle zastosowałem i naprawdę wiem, co robię (historycznie, JavaScript jest środowiskiem, w którym wszystko idzie, i wielu przypisuje jego sukces temu rozciągnięciu)

+0

"kod wprowadza oddzielny obiekt funkcji dla każdej instancji klasy" - nawet jeśli kod używa bezpośrednio 'bind', np. 'foo: foo.bind (null, dep1, dep2)'? – Ben

+0

Tak, właśnie przetestowałem to w Chrome: 'foo.bind (null, 1, 2) === foo.bind (null, 1, 2)' zwraca 'false'. – meriton

+0

Ach, tak, masz rację. Dzięki za potwierdzenie. Również https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind – Ben

3

Prosta: dlaczego?

"Prywatność" jest przerażająco przereklamowana. Nie ukrywa niczego przed każdym, kto naprawdę tego chce. Posiadanie "chronionych" lub "prywatnych" członków jest wyłącznie dla korzyści programisty, w szczególności dla wskazania, w jaki sposób dany członek ma być używany (ten tutaj jest publiczny interfejs API, ten tutaj nie jest, więc nie dotykaj chyba że wiesz, co robi). To wszystko. Konwencja nazewnictwa, jak na przykład podkreślenia początkowe, jest na tyle perfekcyjna, aby ją zaimplementować. Jeśli nazwa użytkownika zaczyna się od podkreślenia, nie dotykaj go, chyba że wiesz, co robisz.

Nie ma istotnej potrzeby pochylania się w tył dalej.

+0

W odpowiedzi na twoje pytanie: "ponieważ z' _foo', podczas pracy we współużytkowanej bazie kodu, nie możesz być pewien, że nie jest używany, ponieważ nazwa jest "tylko nazwą". W tym drugim przypadku zwiększa się zaufanie, poprawiając niefunkcjonalne aspekty kodu. – Ben

+1

Jeśli nie masz zaufania do współpracowników, uczynienie prywatnych członków bardziej prywatnymi nie pomoże. Jest to kwestia komunikacji i/lub przeglądu pomiędzy programistami, a nie problem techniczny, który należy rozwiązać. Jest jeszcze wiele rzeczy, których niezaufani programiści są w stanie zepsuć niż dostęp do prywatnych członków. – deceze

+0

Istnieje wiele problemów związanych z tworzeniem oprogramowania. Wymieniasz kilka. Czy to oznacza, że ​​nie powinniśmy próbować ograniczać ryzyka stwarzanego przez te problemy? – Ben