Jak mogę tworzyć zmienne statyczne w JavaScript?
javascript
variables
static
closures
Rajat
źródło
źródło
someFunc = () => { MyClass.myStaticVariable = 1; }
. Następnie po prostu utwórz metodę statyczną, aby zwrócić element statyczny, npstatic getStatic() { return MyClass.myStaticVariable; }
. Następnie możesz po prostu zadzwonićMyClass.getStatic()
spoza klasy, aby uzyskać dane statyczne!Odpowiedzi:
Jeśli pochodzisz z opartego na klasach, statycznie typowanego języka obiektowego (takiego jak Java, C ++ lub C #) , zakładam, że próbujesz utworzyć zmienną lub metodę powiązaną z „typem”, ale nie z instancją.
Przykład zastosowania „klasycznego” podejścia z funkcjami konstruktora może pomóc w zrozumieniu podstawowych pojęć JavaScript OO:
staticProperty
jest zdefiniowany w obiekcie MyClass (który jest funkcją) i nie ma nic wspólnego z utworzonymi instancjami, JavaScript traktuje funkcje jak obiekty pierwszej klasy , więc będąc obiektem, możesz przypisywać właściwości do funkcji.AKTUALIZACJA: ES6 wprowadził możliwość deklarowania klas za pomocą
class
słowa kluczowego. Jest to cukier składniowy w stosunku do istniejącego dziedziczenia opartego na prototypach.Słowo
static
kluczowe pozwala łatwo zdefiniować właściwości lub metody statyczne w klasie.Zobaczmy powyższy przykład zaimplementowany z klasami ES6:
źródło
privilegedMethod
nie jest to odpowiednik prywatnej metody w OO, ponieważ wygląda na to, że można ją wywołać na instancji MyClass? Czy masz na myśli, że jest uprzywilejowany, ponieważ ma dostępprivateVariable
?this.constructor
można użyć do uzyskania dostępu do zmiennych statycznych z „metod instancji”? Jeśli tak, warto dodać to do odpowiedzi.MyClass.prototype.staticProperty = "baz";
lub być jeszcze bardziej zgodny z zasadami OO, właściwość statyczna powinna być faktycznie zdefiniowana jako funkcja anonimowa,MyClass.prototype.staticProperty = function () {return staticVar;}
tak aby wszystkie instancje miały dostęp do jednej zmiennej, którą można również zmienić za pomocą settera.Możesz skorzystać z faktu, że funkcje JS są również obiektami - co oznacza, że mogą mieć właściwości.
Na przykład, cytując przykład podany w (już nieistniejącym) artykule Zmienne statyczne w JavaScript :
Jeśli wywołasz tę funkcję kilka razy, zobaczysz, że licznik jest zwiększany.
Jest to prawdopodobnie o wiele lepsze rozwiązanie niż przeszukiwanie globalnej przestrzeni nazw za pomocą zmiennej globalnej.
A oto inne możliwe rozwiązanie oparte na zamknięciu: Sztuczka, aby użyć zmiennych statycznych w javascript :
Co daje ci ten sam wynik - z tym wyjątkiem, że zamiast tego wyświetlana jest wartość przyrostowa.
źródło
countMyself.counter = countMyself.counter || initial_value;
jeśli zmienna statyczna nigdy nie będzie falsey (false, 0, null lub pusty ciąg)===
ztypeof
czeków, bo będziesz miał dziwny przymus.Robisz to poprzez IIFE (natychmiast wywołane wyrażenie funkcji):
źródło
możesz użyć arguments.callee do przechowywania zmiennych „statycznych” (jest to również przydatne w funkcji anonimowej):
źródło
arguments.callee
jest przestarzałe.callee
wydawało mi się, że to miło. Zastanawiam się, dlaczego hack postanowili wycofać to ...: |Widziałem kilka podobnych odpowiedzi, ale chciałbym wspomnieć, że ten post najlepiej to opisuje, więc chciałbym się z tobą podzielić.
Oto pobrany z niego kod, który zmodyfikowałem, aby uzyskać kompletny przykład, który, mam nadzieję, daje korzyść społeczności, ponieważ można go użyć jako szablonu projektu dla klas.
Odpowiada również na twoje pytanie:
Biorąc pod uwagę ten przykład, możesz uzyskać dostęp do właściwości / funkcji statycznej w następujący sposób:
A właściwości / funkcje obiektu po prostu jako:
Zauważ, że w podcast.immutableProp () mamy zamknięcie : Odwołanie do _somePrivateVariable jest przechowywane wewnątrz funkcji.
Możesz nawet zdefiniować obiekty pobierające i ustawiające . Spójrz na ten fragment kodu (gdzie
d
jest prototyp obiektu, dla którego chcesz zadeklarować właściwość,y
to zmienna prywatna niewidoczna poza konstruktorem):Definiuje właściwość
d.year
poprzezget
iset
funkcje - jeśli nie określiszset
, właściwość jest tylko do odczytu i nie można jej modyfikować (pamiętaj, że nie pojawi się błąd, jeśli spróbujesz ją ustawić, ale nie da to efektu). Każda nieruchomość ma atrybutywritable
,configurable
(pozwala na zmianę po zgłoszeniu) ienumerable
(pozwalają na zastosowanie go jako wyliczający), które są domyślniefalse
. Możesz ustawić je zadefineProperty
pomocą trzeciego parametru, npenumerable: true
.Prawidłowa jest również następująca składnia:
która definiuje właściwość do odczytu / zapisu, właściwość
a
tylko do odczytub
i właściwość tylko do zapisuc
, za pośrednictwem któreja
można uzyskać dostęp do właściwości .Stosowanie:
Uwagi:
Aby uniknąć nieoczekiwanego zachowania w przypadku zapomnienia
new
słowa kluczowego, sugeruję dodanie do funkcji następujących elementówPodcast
:Teraz obie następujące instancje będą działać zgodnie z oczekiwaniami:
Instrukcja „new” tworzy nowy obiekt i kopiuje wszystkie właściwości i metody, tj
Należy również zauważyć, że w niektórych sytuacjach użyteczne może być użycie
return
instrukcji w funkcji konstruktora,Podcast
aby zwrócić niestandardowy obiekt chroniący funkcje, na których klasa wewnętrznie polega, ale które należy ujawnić. Jest to wyjaśnione dalej w rozdziale 2 (Przedmioty) serii artykułów.Możesz to powiedzieć
a
ib
odziedziczyć poPodcast
. Co teraz, jeśli chcesz dodać do Podcastu metodę, która będzie obowiązywała dla wszystkich po tym, jak zostałaa
ib
została utworzona? W takim przypadku użyj.prototype
następujących opcji:Teraz zadzwoń
a
ib
jeszcze raz:Więcej informacji na temat prototypów można znaleźć tutaj . Jeśli chcesz zrobić więcej spadków, sugeruję przyjrzeć się temu .
W serii artykułów mam wymienione powyżej są bardzo zalecane , aby przeczytać, obejmują one również następujące tematy:
Pamiętaj, że „funkcja” automatycznego wstawiania średnika w JavaScript (jak wspomniano w 6.) bardzo często powoduje dziwne problemy w kodzie. Dlatego wolę traktować to jako błąd niż funkcję.
Jeśli chcesz przeczytać więcej, oto dość interesujący artykuł MSDN na te tematy, niektóre z nich opisane zawierają jeszcze więcej szczegółów.
Co jest interesujące, aby przeczytać , jak również (także obejmujące zagadnienia wymienione powyżej) są te artykuły z MDN JavaScript Przewodnik :
Jeśli chcesz wiedzieć, jak emulować
out
parametry c # (np. InDateTime.TryParse(str, out result)
) w JavaScript, możesz znaleźć przykładowy kod tutaj.Ci z was, którzy pracują z IE (który nie ma konsoli JavaScript, chyba że otworzysz narzędzia programistyczne za pomocą F12i otworzysz kartę konsoli), mogą skorzystać z następującego fragmentu kodu . Pozwala na użycie
console.log(msg);
jak w powyższych przykładach. Wystarczy wstawić przedPodcast
funkcją.Dla Twojej wygody oto powyższy kod w jednym pełnym pojedynczym fragmencie kodu:
Pokaż fragment kodu
Uwagi:
Kilka dobrych wskazówek, wskazówek i zaleceń dotyczących programowania JavaScript można znaleźć tutaj (najlepsze praktyki JavaScript) i tam („var” kontra „let”) . Zalecany jest również ten artykuł o niejawnych typecastach (przymus) .
Wygodnym sposobem używania klas i kompilowania ich w JavaScript jest TypeScript. Oto plac zabaw, na którym można znaleźć przykłady pokazujące, jak to działa. Nawet jeśli obecnie nie używasz TypeScript, możesz rzucić okiem, ponieważ możesz porównać TypeScript z wynikiem JavaScript w widoku obok siebie. Większość przykładów jest prosta, ale jest też przykład Raytracer, który możesz wypróbować natychmiast. Szczególnie polecam zapoznanie się z przykładami „Korzystanie z klas”, „Korzystanie z dziedziczenia” i „Korzystanie z ogólnych” poprzez wybranie ich w oknie combobox - są to ładne szablony, które można natychmiast wykorzystać w JavaScript. Maszynopis jest używany z Angular.
Aby uzyskać enkapsulację zmiennych lokalnych, funkcji itp. W JavaScript, sugeruję użycie wzoru podobnego do następującego (JQuery używa tej samej techniki):
Oczywiście możesz - i powinieneś - umieścić kod skryptu w osobnym
*.js
pliku; jest to po prostu napisane w wierszu, aby skrót był krótki.Funkcje samo-wywołujące (znane również jako IIFE = wyrażenie funkcji natychmiastowego wywołania) opisano tutaj bardziej szczegółowo .
źródło
źródło
Zaktualizowana odpowiedź:
W ECMAScript 6 można tworzyć funkcje statyczne za pomocą
static
słowa kluczowego:Klasy ES6 nie wprowadzają żadnej nowej semantyki dla statyki. W ES5 możesz zrobić to samo:
Możesz przypisać do właściwości,
Foo
ponieważ w JavaScript funkcje są obiektami.źródło
Foo.bar;
zwraca funkcję przypisaną do niego, a nie ciąg zwracany przez funkcję, jak sugeruje komentarz.bar
właściwośćFoo
do3
tak:Foo.bar = 3;
Poniższy przykład i wyjaśnienie pochodzą z książki Professional JavaScript for Web Developers 2nd Edition autorstwa Nicholasa Zakasa. Oto odpowiedź, której szukałem, więc pomyślałem, że warto ją tutaj dodać.
Person
Konstruktor w tym przykładzie ma dostęp do prywatnej nazwy zmiennej, jak wykonaćgetName()
isetName()
metod. Korzystając z tego wzorca, zmienna nazwy staje się statyczna i będzie używana we wszystkich instancjach. Oznacza to, że wywołaniesetName()
jednej instancji wpływa na wszystkie inne instancje. WywołaniesetName()
lub utworzenie nowejPerson
instancji ustawia zmienną nazwy na nową wartość. Powoduje to, że wszystkie wystąpienia zwracają tę samą wartość.źródło
Jeśli używasz nowej składni klasy , możesz teraz wykonać następujące czynności:
To skutecznie tworzy zmienną statyczną w JavaScript.
źródło
MyClass
zdefiniowana poza konstrukcją klasy.Jeśli chcesz zadeklarować zmienne statyczne do tworzenia stałych w aplikacji, uznałem, że jest to najbardziej uproszczone podejście
źródło
Informacje o
class
wprowadzonym przez ECMAScript 2015. Pozostałe odpowiedzi nie są całkowicie jasne.Oto przykład pokazujący, jak utworzyć statyczny var
staticVar
za pomocąClassName
.var
składnia:Aby uzyskać dostęp do zmiennej statycznej, używamy
.constructor
właściwości, która zwraca odwołanie do funkcji konstruktora obiektów, która utworzyła klasę. Możemy to nazwać dwoma utworzonymi instancjami:źródło
Istnieją inne podobne odpowiedzi, ale żadna z nich do mnie nie przemówiła. Oto, z czym skończyłem:
źródło
Oprócz reszty istnieje obecnie projekt (propozycja etapu 2 ) dotyczący propozycji ECMA, który wprowadza pola
static
publiczne na zajęciach. ( rozważono prywatne pola )Na przykładzie z propozycji proponowana
static
składnia będzie wyglądać następująco:i być równoważne z następującymi, które inni podkreślili:
Następnie możesz uzyskać do niego dostęp za pośrednictwem
CustomDate.epoch
.Możesz śledzić nową propozycję w
proposal-static-class-features
.Obecnie babel obsługuje tę funkcję za pomocą wtyczki właściwości klasy transform, której można użyć. Dodatkowo, choć wciąż jest w toku,
V8
wdraża go .źródło
Możesz utworzyć zmienną statyczną w JavaScript tak jak poniżej. Oto
count
zmienna statyczna.Możesz przypisać wartości do zmiennej statycznej za pomocą
Person
funkcji lub dowolnego z instancji:źródło
Jeśli chcesz utworzyć globalną zmienną statyczną:
Zastąp zmienną poniższą:
źródło
Najbliższą rzeczą w JavaScript do zmiennej statycznej jest zmienna globalna - jest to po prostu zmienna zadeklarowana poza zakresem literału funkcji lub obiektu:
Inną rzeczą, którą możesz zrobić, to przechowywać zmienne globalne w dosłownym obiekcie:
A następnie uzyskać dostęp do variabels tak:
foo.bar
.źródło
Aby skondensować wszystkie koncepcje klas tutaj, przetestuj to:
Cóż, innym sposobem na przyjrzenie się najlepszym praktykom w tych sprawach jest po prostu zobaczenie, jak coffeescript tłumaczy te pojęcia.
źródło
W JavaScript zmienne są domyślnie statyczne . Przykład :
Wartość x jest zwiększana o 1 co 1000 milisekund.
Będzie drukować 1,2,3 itd
źródło
Istnieje inne podejście, które rozwiązało moje wymagania po przejrzeniu tego wątku. Zależy to dokładnie od tego, co chcesz osiągnąć dzięki „zmiennej statycznej”.
Globalna właściwość sessionStorage lub localStorage pozwala na przechowywanie danych przez czas trwania sesji lub przez czas nieokreślony, aż do wyraźnego wyczyszczenia. Pozwala to na współdzielenie danych między wszystkimi oknami, ramkami, panelami kart, wyskakującymi oknami itp. Strony / aplikacji i jest znacznie potężniejszy niż zwykła „zmienna statyczna / globalna” w jednym segmencie kodu.
Pozwala to uniknąć wszelkich problemów związanych z zakresem, czasem życia, semantyką, dynamiką itp. Zmiennych globalnych najwyższego poziomu, tj. Window.myglobal. Nie wiem, jak wydajna jest, ale nie jest to ważne w przypadku niewielkich ilości danych, do których dostęp jest uzyskiwany przy niewielkich prędkościach.
Łatwo dostępne jako „sessionStorage.mydata = cokolwiek” i pobrane podobnie. Zobacz „JavaScript: The Definitive Guide, Sixth Edition”, David Flanagan, ISBN: 978-0-596-80552-4, rozdział 20, sekcja 20.1. Można go łatwo pobrać jako plik PDF za pomocą prostego wyszukiwania lub w subskrypcji O'Reilly Safaribooks (na wagę złota).
źródło
Funkcja / klasy zezwala tylko na jeden konstruktor dla swojego zakresu obiektowego.
Function Hoisting, declarations & expressions
Zamknięcia - kopie zamknięcia są funkcją z zachowanymi danymi.
Klasy funkcji ES5 : wykorzystuje Object.defineProperty (O, P, atrybuty)
Utworzono niektóre metody za pomocą `` , aby każdy raz mógł łatwo zrozumieć klasy funkcji.
Poniższy fragment kodu ma na celu sprawdzenie, czy każda instancja ma własną kopię elementów instancji i wspólnych elementów statycznych.
Klasy ES6: Klasy ES2015 są prostym cukrem w stosunku do prototypowego wzoru OO. Posiadanie pojedynczej wygodnej formy deklaratywnej ułatwia stosowanie wzorców klas i zachęca do interoperacyjności. Klasy obsługują dziedziczenie oparte na prototypach, super wywołania, metody instancji i statyczne oraz konstruktory.
Przykład : odnieś mój poprzedni post.
źródło
Istnieją 4 sposoby emulacji lokalnych zmiennych statycznych dla funkcji w JavaScript.
Metoda 1: Korzystanie z właściwości obiektu funkcji (obsługiwane w starych przeglądarkach)
Metoda 2: Korzystanie z zamknięcia, wariant 1 (obsługiwany w starych przeglądarkach)
Metoda 3: Użycie zamknięcia, wariant 2 (obsługiwany również w starszych przeglądarkach)
Metoda 4: Użycie zamknięcia, wariant 3 (wymaga obsługi EcmaScript 2015)
źródło
Możesz zdefiniować funkcje statyczne w JavaScript za pomocą
static
słowa kluczowego:W chwili pisania tego tekstu nadal nie można zdefiniować właściwości statycznych (innych niż funkcje) w klasie. Właściwości statyczne są nadal propozycją etapu 3 , co oznacza, że nie są jeszcze częścią JavaScript. Jednak nic nie stoi na przeszkodzie, abyś po prostu przypisał klasę, tak jak w przypadku każdego innego obiektu:
Uwaga końcowa: należy zachować ostrożność podczas używania obiektów statycznych z dziedziczeniem - wszystkie dziedziczone klasy współużytkują tę samą kopię obiektu .
źródło
W JavaScript nie ma statycznego terminu ani słowa kluczowego, ale możemy umieścić takie dane bezpośrednio w obiekcie funkcji (jak w każdym innym obiekcie).
źródło
Często używam zmiennych funkcji statycznych i szkoda, że JS nie ma do tego wbudowanego mechanizmu. Zbyt często widzę kod, w którym zmienne i funkcje są zdefiniowane w zakresie zewnętrznym, nawet jeśli są one używane tylko w jednej funkcji. To brzydkie, podatne na błędy i po prostu prosi o kłopoty ...
Wymyśliłem następującą metodę:
Dodaje to metodę „statyki” do wszystkich funkcji (tak, rozluźnij się wokół niej), po wywołaniu doda pusty obiekt (_statics) do obiektu funkcji i zwróci go. Jeśli dostarczona jest funkcja init, statystyka zostanie ustawiona na wynik init ().
Następnie możesz wykonać:
Porównując to do IIFE, która jest drugą poprawną odpowiedzią, ma to tę wadę, że dodaje jedno przypisanie i jedno, jeśli przy każdym wywołaniu funkcji i dodaje do funkcji element „_statics”, jednak jest kilka zalet: argumenty są na góra nie w funkcji wewnętrznej, użycie „statycznego” w wewnętrznym kodzie funkcji jest jawne z „_s”. przedrostek i ogólnie łatwiej jest patrzeć i rozumieć.
źródło
Podsumowanie:
W
ES6
/ ES 2015class
słowo kluczowe zostało wprowadzone wraz zestatic
słowem kluczowym towarzyszącym . Należy pamiętać, że jest to cukier składniowy w porównaniu z prototypowym modelem dziedziczenia, który ucieleśnia skrypt javavscript. Słowostatic
kluczowe działa w następujący sposób dla metod:źródło
Użyłem prototypu i tak to działało:
lub za pomocą statycznego gettera:
źródło
Zmienne na poziomie okna są trochę podobne do statyki w tym sensie, że można użyć bezpośredniego odniesienia i są one dostępne dla wszystkich części aplikacji
źródło
W Javascript nie ma czegoś takiego jak zmienna statyczna. Ten język jest zorientowany obiektowo na prototypy, więc nie ma klas, ale prototypy, z których obiekty same się „kopiują”.
Możesz je symulować za pomocą zmiennych globalnych lub prototypowania (dodając właściwość do prototypu):
źródło
Function.prototype
function circle() {}
|circle.prototype
|circle.prototype.pi = 3.14
|circle.prototype
|Function.prototype
|Function.__proto__
(jeśli o to ci chodziło)Pracując ze stronami MVC korzystającymi z jQuery, chciałbym mieć pewność, że akcje AJAX w ramach niektórych programów obsługi zdarzeń będą mogły zostać wykonane dopiero po zakończeniu poprzedniego żądania. W tym celu używam „statycznej” zmiennej obiektowej jqXHR.
Biorąc pod uwagę następujący przycisk:
Zasadniczo używam takiego IIFE dla mojego modułu obsługi kliknięć:
źródło
Jeśli chcesz użyć prototypu, jest na to sposób
W ten sposób będziesz mógł uzyskać dostęp do zmiennej licznika z dowolnej instancji, a każda zmiana właściwości zostanie natychmiast odzwierciedlona !!
źródło