Aby utworzyć klasę JavaScript metodą publiczną, zrobiłbym coś takiego:
function Restaurant() {}
Restaurant.prototype.buy_food = function(){
// something here
}
Restaurant.prototype.use_restroom = function(){
// something here
}
W ten sposób użytkownicy mojej klasy mogą:
var restaurant = new Restaurant();
restaurant.buy_food();
restaurant.use_restroom();
Jak utworzyć prywatną metodę, która może być wywoływana przez metody buy_food
i use_restroom
, ale nie zewnętrznie przez użytkowników klasy?
Innymi słowy, chcę, aby moja metoda implementacji była w stanie:
Restaurant.prototype.use_restroom = function() {
this.private_stuff();
}
Ale to nie powinno działać:
var r = new Restaurant();
r.private_stuff();
Jak zdefiniować private_stuff
jako metodę prywatną, aby oba były prawdziwe?
Przeczytałem kilka słów Douga Crockforda, ale nie wydaje się, że metody „prywatne” można wywoływać metodami publicznymi, a metody „uprzywilejowane” można wywoływać zewnętrznie.
javascript
oop
private-methods
Wayne Kao
źródło
źródło
Korzystanie z funkcji wywoływania i wywoływania
JavaScript używa prototypów i nie ma klas (ani metod w tym zakresie), takich jak języki obiektowe. Programista JavaScript musi myśleć w JavaScript.
Cytat z Wikipedii:
Rozwiązanie wykorzystujące funkcję auto-wywoływania i funkcję call do wywołania prywatnej „metody”:
Funkcja call pozwala nam wywoływać funkcję prywatną z odpowiednim kontekstem (
this
).Łatwiej dzięki Node.js
Jeśli używasz node.js , nie potrzebujesz IIFE, ponieważ możesz skorzystać z systemu ładowania modułów :
Załaduj plik:
(eksperymentalnie) ES7 z operatorem wiązania
Operator powiązania
::
jest propozycją ECMAScript i jest implementowany w Babel ( etap 0 ).Załaduj plik:
źródło
.call
części.f()
w javascript (nie w tej chwili)..call
) i małą pamięć (brak funkcji w instancji)? Czy to w ogóle istnieje?Możesz symulować takie metody prywatne:
Więcej informacji na temat tej techniki tutaj: http://webreflection.blogspot.com/2008/04/natural-javascript-private-methods.html
źródło
W tych sytuacjach, gdy masz publiczny interfejs API i potrzebujesz prywatnych / publicznych metod / właściwości, zawsze używam Wzorca modułu. Ten wzór stał się popularny w bibliotece YUI, a szczegóły można znaleźć tutaj:
http://yuiblog.com/blog/2007/06/12/module-pattern/
Jest to naprawdę proste i łatwe do zrozumienia dla innych programistów. Dla prostego przykładu:
źródło
aPrivateMethod = function() { MYLIB.aPublicProperty}
?Oto klasa, którą stworzyłem, aby zrozumieć, co Douglas Crockford zaproponował w swojej witrynie Private Members w JavaScript
źródło
that
jest używany zamiast,this
aby uniknąć problemów z zasięgiem, gdy funkcje są powiązane z innym obiektem. Tutaj są przechowywanethis
wthat
i nigdy ponownym użyciem, która jest taka sama, jak nie robi tego w ogóle. Powinieneś zmienić zathis
pomocąthat
wszystkichConstructor
funkcji wewnętrznych (nie deklaracji metod). Jeśliemployee
jestapply
edytowane lubcall
edytowane w jakiś sposób, metody te mogą rzucać, ponieważthis
zostaną niepoprawnie powiązane.Przywołałem to: EDYCJA: Właściwie ktoś powiązał to samo rozwiązanie. Hه!
źródło
var getAwayVehicle = new Car(100);
gdzie100
jest prędkość i chcesz ostrzec prędkość. Dzięki!var Car = function(speed) { this.speed = speed; }
i `return {constructor: Car, ...`Myślę, że takie pytania wciąż pojawiają się z powodu braku zrozumienia zamknięć. Zamknięcia są najważniejsze w JS. Każdy programista JS musi poczuć jego esencję.
1. Przede wszystkim musimy wprowadzić osobny zakres (zamknięcie).
2. W tym obszarze możemy robić, co chcemy. I nikt się o tym nie dowie.
3. Aby świat wiedział o naszej klasie restauracji, musimy ją zwrócić po zamknięciu.
4. Na koniec mamy:
5. Podejście to ma również potencjał dziedziczenia i tworzenia szablonów
Mam nadzieję, że to pomoże komuś lepiej zrozumieć ten temat
źródło
Osobiście wolę następujący wzór do tworzenia klas w JavaScript:
Jak widać, pozwala zdefiniować zarówno właściwości klasy, jak i właściwości instancji, z których każda może być publiczna i prywatna.
Próbny
Zobacz także to skrzypce .
źródło
Całe to zamknięcie będzie cię kosztować. Upewnij się, że przetestujesz wpływ na szybkość, szczególnie w IE. Przekonasz się, że lepiej się czujesz dzięki konwencji nazewnictwa. Nadal istnieje wielu użytkowników korporacyjnych, którzy są zmuszeni do korzystania z IE6 ...
źródło
Nie bądź taki gadatliwy. To Javascript. Użyj konwencji nazewnictwa .
Po latach pracy w klasach es6, niedawno rozpocząłem pracę nad projektem es5 (używając wymagającego JS, który już jest bardzo gadatliwy). Cały czas omawiałem wszystkie wymienione tutaj strategie i wszystko sprowadza się do użycia konwencji nazewnictwa :
private
. Inni programiści, którzy wprowadzają Javascript, będą z góry o tym wiedzieć. Dlatego prosta konwencja nazewnictwa jest więcej niż wystarczająca. Prosta konwencja nazewnictwa z prefiksem ze znakiem podkreślenia rozwiązuje problem zarówno właściwości prywatnych, jak i metod prywatnych.my-tooltip.js
źródło
define
Iconstructor
a sama struktura. Chociaż zgadzam się głównie z odpowiedzią, zacząłem pracować z JS z dużym wpływem OOP, a nawet przeskoczyłem zbyt wcześnie na TS, ponieważ miałem wcześniejsze doświadczenie w C #. Myślę, że muszę się tego oduczyć i zrozumieć paradygmat prototypowania / procedury. (upvoted, btw)Możesz to zrobić teraz za pomocą prywatnych metod es10 . Musisz tylko dodać
#
przed nazwą metody.źródło
Wybierz jedno z rozwiązań zgodnych z prywatnym lub uprzywilejowanym wzorem Crockford . Na przykład:
W każdym przypadku, gdy atakujący nie ma prawa „wykonania” w kontekście JS, nie ma możliwości uzyskania dostępu do jakichkolwiek pól lub metod „publicznych” lub „prywatnych”. W przypadku, gdy atakujący ma taki dostęp, może wykonać jedną linijkę:
Zauważ, że powyższy kod jest ogólny dla prywatności wszystkich konstruktorów. Nie powiedzie się z niektórymi rozwiązaniami tutaj, ale powinno być jasne, że prawie wszystkie rozwiązania oparte na zamknięciu mogą zostać zepsute w ten sposób z różnymi
replace()
parametrach.Po wykonaniu tego każdy obiekt utworzony za pomocą
new Foo()
będzie miałeval
metodę, która może zostać wywołana w celu zwrócenia lub zmiany wartości lub metod zdefiniowanych w zamknięciu konstruktora, np .:Jedyny problem, jaki mogę z tym zobaczyć, nie działa w przypadkach, w których istnieje tylko jedna instancja i jest tworzona podczas ładowania. Ale wtedy nie ma powodu, aby faktycznie definiować prototyp. W takim przypadku atakujący może po prostu odtworzyć obiekt zamiast konstruktora, o ile ma on możliwość przekazania tych samych parametrów (np. Są one stałe lub obliczane na podstawie dostępnych wartości).
Moim zdaniem dzięki temu rozwiązanie Crockforda jest bezużyteczne.Ponieważ „prywatność” jest łatwo łamana, wady jego rozwiązania (zmniejszona czytelność i łatwość konserwacji, zmniejszona wydajność, zwiększona pamięć) sprawiają, że metoda oparta na prototypach „brak prywatności” jest lepszym wyborem.
Ja zwykle korzystam wiodącym podkreślenia aby oznaczyć
__private
i_protected
metod i pól (styl Perl), ale idea posiadania prywatności w JavaScripcie tylko pokazuje, w jaki sposób jest to język niezrozumiany.Dlatego nie zgadzam się z Crockfordem wyjątkiem jego pierwszego zdania.
Jak więc uzyskać prawdziwą prywatność w JS? Umieść wszystko, co jest wymagane, aby być prywatnym po stronie serwera i używaj JS do wykonywania połączeń AJAX.
źródło
(function () {allMyStuff}());
sposób, aby nie ujawniać niczego globalnego.f.eval('nameOfVariable')
gdy nie wiesz, co to'nameOfVariable'
jest ...Apoteoza Wzorca Modułu: Wzorzec Modułu Objawienia
Zgrabne małe rozszerzenie do bardzo solidnego wzoru.
źródło
Jeśli chcesz mieć pełny zakres funkcji publicznych i prywatnych z możliwością dostępu funkcji publicznych do funkcji publicznych, kod układu dla takiego obiektu:
źródło
new MyObject
, prototypMyObject
jest zastępowany tymi samymi wartościami..prototype
konstruktora.Podobne do georgebrock, ale trochę mniej gadatliwe (IMHO) Masz problemy z zrobieniem tego w ten sposób? (Nigdzie go nie widziałem)
edycja: Zdałem sobie sprawę, że jest to trochę bezużyteczne, ponieważ każda niezależna instancja ma swoją własną kopię metod publicznych, co podważa użycie prototypu.
źródło
Oto, co do tej pory najbardziej podobało mi się w zakresie prywatnych / publicznych metod / członków i tworzenia instancji w javascript:
oto artykuł: http://www.sefol.com/?p=1090
a oto przykład:
JSFiddle: http://jsfiddle.net/northkildonan/kopj3dt3/1/
źródło
Wzorzec modułu jest poprawny w większości przypadków. Ale jeśli masz tysiące instancji, klasy oszczędzają pamięć. Jeśli problemem jest oszczędzanie pamięci, a twoje obiekty zawierają niewielką ilość prywatnych danych, ale mają wiele funkcji publicznych, to chcesz, aby wszystkie funkcje publiczne działały w .prototypie, aby oszczędzać pamięć.
Oto co wymyśliłem:
Obiekt
priv
zawiera właściwości prywatne. Jest dostępny poprzez funkcję publicznągetPriv()
, ale ta funkcja zwraca,false
chyba że ją przejdzieszsecret
, i jest to znane tylko w głównym zamknięciu.źródło
A co z tym?
Wyszukiwanie zmiennych prywatnych jest niemożliwe poza zakresem funkcji natychmiastowej. Nie ma powielania funkcji, oszczędzając pamięć.
Minusem jest to, że wyszukiwanie zmiennych prywatnych jest nieporęczne,
privateVars[this.id].cooked
jest śmiesznie pisać. Istnieje również dodatkowa zmienna „id”.źródło
Restaurant
jakundefined
bo nie masz nic powrocie z funkcji anonimowej.Restaurant
została wyrzucona do pamięci , jej wartości pozostają w środkuprivateVars
. W tym przypadkuWeakMap
może być dobrym zamiennikiemArray
.Zawiń cały kod w funkcję anonimową: wtedy wszystkie funkcje będą prywatne, TYLKO funkcje dołączone do
window
obiektu:Użyj tego :
SKRZYPCE
źródło
Wolę przechowywać prywatne dane w powiązanym
WeakMap
. Pozwala to zachować publiczne metody na prototypie, do którego należą. Jest to najwydajniejszy sposób radzenia sobie z tym problemem w przypadku dużej liczby obiektów.źródło
Funkcje prywatne nie mogą uzyskać dostępu do zmiennych publicznych przy użyciu wzorca modułu
źródło
Ponieważ wszyscy publikowali tutaj swój własny kod, ja też to zrobię ...
Lubię Crockforda, ponieważ wprowadził w JavaScript prawdziwe wzorce obiektowe. Ale wpadł też na nowe nieporozumienie, „tamte”.
Dlaczego więc używa słowa „to = to”? Nie ma to w ogóle nic wspólnego z funkcjami prywatnymi. Ma to związek z funkcjami wewnętrznymi!
Ponieważ według Crockforda jest to błędny kod:
Więc zasugerował zrobienie tego:
Tak jak powiedziałem, jestem całkiem pewien, że Crockford się mylił, wyjaśniając to i to (ale jego kod jest z pewnością poprawny). A może po prostu oszukiwał świat Javascript, aby wiedzieć, kto kopiuje jego kod? Nie wiem ... Nie jestem maniakiem przeglądarki; D
EDYTOWAĆ
Ach, o to w tym wszystkim chodzi: Co to znaczy „var that = this;” znaczy w JavaScript?
Więc Crockie naprawdę nie miał racji w swoim wyjaśnieniu ... ale miał rację w swoim kodzie, więc nadal jest świetnym facetem. :))
źródło
Ogólnie dodałem tymczasowo obiekt prywatny _ do obiektu. Musisz dokładnie otworzyć prywatność w „Konstruktorze mocy” dla metody. Jeśli wywołasz metodę z prototypu, będziesz mógł zastąpić metodę prototypu
Udostępnij publiczną metodę w „Konstruktorze zasilania”: (ctx to kontekst obiektu)
Teraz mam tę otwartą prywatność:
źródło
Oto co wypracowałem:
Potrzebuje jednej klasy kodu cukru, który można znaleźć tutaj . Obsługuje również chronione, spadkowe, wirtualne, statyczne rzeczy ...
źródło
https://github.com/nooning/JSClass
źródło
Stworzyłem nowe narzędzie, które pozwala mieć prawdziwe prywatne metody na prototypie https://github.com/TremayneChrist/ProtectJS
Przykład:
źródło
_private
metoda?Musisz zamknąć faktyczną funkcję konstruktora, w której możesz zdefiniować swoje prywatne metody. Aby zmienić dane instancji za pomocą tych prywatnych metod, musisz dać im to „to”, albo jako argument funkcji, albo przez wywołanie tej funkcji za pomocą .apply (this):
źródło
new Restaurant
będzie miał własnegorestaurant
konstruktora, a „prototyp” będzie całkowicie nadużywany.Wiem, że jest trochę za późno, ale co powiesz na to?
źródło
Na to pytanie jest już wiele odpowiedzi, ale nic nie odpowiada moim potrzebom. Więc wymyśliłem własne rozwiązanie, mam nadzieję, że będzie przydatne dla kogoś:
Jak widać, ten system działa, gdy używa się tego typu klas w javascript. O ile się zorientowałem, żadna z wyżej wymienionych metod nie działała.
źródło
Zobacz tę odpowiedź, aby uzyskać czyste i proste rozwiązanie „klasowe” z prywatnym i publicznym interfejsem oraz obsługą kompozycji
źródło