Wie kann ich statische Variablen in Javascript erstellen?
javascript
variables
static
closures
Rajat
quelle
quelle
someFunc = () => { MyClass.myStaticVariable = 1; }
. Erstellen Sie dann einfach eine statische Methode, um das statische Element zurückzugeben, zstatic getStatic() { return MyClass.myStaticVariable; }
. Dann können Sie einfachMyClass.getStatic()
von außerhalb der Klasse anrufen , um die statischen Daten zu erhalten!Antworten:
Wenn Sie aus einer klassenbasierten, statisch typisierten objektorientierten Sprache stammen (wie Java, C ++ oder C #) gehen Sie davon aus, dass Sie versuchen, eine Variable oder Methode zu erstellen, die einem "Typ" zugeordnet ist, jedoch keiner Instanz.
Ein Beispiel mit einem "klassischen" Ansatz mit Konstruktorfunktionen könnte Ihnen möglicherweise dabei helfen, die Konzepte von grundlegendem OO-JavaScript zu verstehen:
staticProperty
wird im MyClass-Objekt (das eine Funktion ist) definiert und hat nichts mit den erstellten Instanzen zu tun. JavaScript behandelt Funktionen als erstklassige Objekte . Als Objekt können Sie einer Funktion also Eigenschaften zuweisen.UPDATE: ES6 hat die Möglichkeit eingeführt , Klassen über das zu deklarieren
class
Schlüsselwort . Es ist Syntaxzucker über der vorhandenen prototypbasierten Vererbung.Das
static
Schlüsselwort können Sie auf einfache Weise statische Eigenschaften oder Methoden in einer Klasse definieren.Sehen wir uns das obige Beispiel an, das mit ES6-Klassen implementiert wurde:
quelle
privilegedMethod
entspricht dies nicht einer privaten Methode in OO, da es den Anschein hat, als könnte es auf einer Instanz von MyClass aufgerufen werden? Meinst du, es ist privilegiert, weil es zugreifen kannprivateVariable
?this.constructor
werden, um über "Instanzmethoden" auf die statischen Variablen zuzugreifen? Wenn ja, lohnt es sich, es der Antwort hinzuzufügen.MyClass.prototype.staticProperty = "baz";
oder noch korrekter zu OO-Prinzipien sein, die statische Eigenschaft sollte tatsächlich als anonyme Funktion definiertMyClass.prototype.staticProperty = function () {return staticVar;}
werden, damit alle Instanzen auf eine einzelne Variable zugreifen, die auch mit einem Setter geändert werden kann.Sie können die Tatsache ausnutzen, dass JS-Funktionen auch Objekte sind - was bedeutet, dass sie Eigenschaften haben können.
Beispiel: Zitieren Sie das Beispiel aus dem (jetzt verschwundenen) Artikel Statische Variablen in Javascript :
Wenn Sie diese Funktion mehrmals aufrufen, wird der Zähler erhöht.
Und dies ist wahrscheinlich eine viel bessere Lösung, als den globalen Namespace mit einer globalen Variablen zu polieren.
Und hier ist eine andere mögliche Lösung, die auf einem Abschluss basiert: Trick, statische Variablen in Javascript zu verwenden :
Damit erhalten Sie die gleiche Art von Ergebnis - außer dass diesmal der inkrementierte Wert zurückgegeben wird, anstatt angezeigt zu werden.
quelle
countMyself.counter = countMyself.counter || initial_value;
wenn die statische Variable niemals falsch sein wird (false, 0, null oder leere Zeichenfolge)===
fürtypeof
Schecks, sonst bekommen Sie einen seltsamen Zwang.Sie tun dies über ein IIFE (sofort aufgerufener Funktionsausdruck):
quelle
Sie können argument.callee verwenden, um "statische" Variablen zu speichern (dies ist auch in anonymen Funktionen nützlich):
quelle
arguments.callee
ist veraltet.callee
schien mir eine nette Sache zu sein. Ich frage mich, warum der Hack sie beschlossen hat, dies zu verwerfen ...: |Ich habe ein paar ähnliche Antworten gesehen, aber ich möchte diesen Beitrag erwähnen es am besten beschreibt, also möchte ich es mit Ihnen teilen.
Hier ist ein Code, den ich geändert habe, um ein vollständiges Beispiel zu erhalten, das hoffentlich der Community zugute kommt, da es als Entwurfsvorlage für Klassen verwendet werden kann.
Es beantwortet auch Ihre Frage:
In diesem Beispiel können Sie wie folgt auf die statischen Eigenschaften / Funktionen zugreifen :
Und die Objekteigenschaften / funktionieren einfach wie folgt:
Beachten Sie, dass in podcast.immutableProp () ein Abschluss vorliegt : Der Verweis auf _somePrivateVariable bleibt in der Funktion erhalten.
Sie können sogar Getter und Setter definieren . Schauen Sie sich dieses Code-Snippet an (wo
d
sich der Prototyp des Objekts befindet, für den Sie eine Eigenschaft deklarieren möchten,y
ist eine private Variable, die außerhalb des Konstruktors nicht sichtbar ist):Es definiert die Eigenschaft
d.year
überget
undset
Funktionen - wenn Sie nichts angebenset
, ist die Eigenschaft schreibgeschützt und kann nicht geändert werden (beachten Sie, dass Sie keine Fehlermeldung erhalten, wenn Sie versuchen, sie festzulegen , dies hat jedoch keine Auswirkungen). Jede Eigenschaft hat die Attributewritable
,configurable
(lassen Änderung nach Anmeldung) undenumerable
(lassen Sie es als Aufzählungs verwenden), die standardmäßig sindfalse
. Sie können sie überdefineProperty
im 3. Parameter einstellen , zenumerable: true
.Was auch gültig ist, ist diese Syntax:
a
Dies definiert eine lesbare / beschreibbare Eigenschaft , eine schreibgeschützte Eigenschaftb
und eine schreibgeschützte Eigenschaftc
, über die auf die Eigenschafta
zugegriffen werden kann.Verwendungszweck:
Anmerkungen:
Um unerwartetes Verhalten zu vermeiden, falls Sie das
new
Schlüsselwort vergessen haben , sollten Sie der Funktion Folgendes hinzufügenPodcast
:Jetzt funktionieren beide der folgenden Instanziierungen wie erwartet:
Die 'neue' Anweisung erstellt ein neues Objekt und kopiert alle Eigenschaften und Methoden, d. H.
Beachten Sie auch, dass es in einigen Situationen nützlich sein kann, die
return
Anweisung in der KonstruktorfunktionPodcast
zu verwenden, um benutzerdefinierte Objektschutzfunktionen zurückzugeben, auf die sich die Klasse intern stützt, die jedoch verfügbar gemacht werden müssen. Dies wird in Kapitel 2 (Objekte) der Artikelserie näher erläutert.Das kann man sagen
a
undb
erben vonPodcast
. Was ist nun, wenn Sie Podcast eine Methode hinzufügen möchten, die für alle nacha
undb
nach der Instanziierung gilt? Verwenden Sie in diesem Fall.prototype
Folgendes:Rufen Sie jetzt an
a
und nochb
einmal:Weitere Details zu Prototypen finden Sie hier . Wenn Sie mehr Vererbung vornehmen möchten, schlage ich vor, dies zu prüfen .
Es wird dringend empfohlen , die oben erwähnten Artikelserien zu lesen. Sie enthalten auch die folgenden Themen:
Beachten Sie, dass das automatische Einfügen von Semikolons in JavaScript (wie in Abschnitt 6 erwähnt) sehr häufig für seltsame Probleme in Ihrem Code verantwortlich ist. Daher würde ich es eher als Fehler als als Feature betrachten.
Wenn Sie mehr lesen möchten, finden Sie hier einen interessanten MSDN-Artikel zu diesen Themen. Einige der dort beschriebenen Artikel enthalten noch mehr Details.
Was ist interessant zu lesen , wie gut (auch die Themen abdeckt wie oben erwähnt) sind die Artikel aus dem MDN JavaScript - Führer :
Wenn Sie wissen möchten, wie man c #
out
-Parameter (wie inDateTime.TryParse(str, out result)
) in JavaScript emuliert , finden Sie hier Beispielcode.Diejenigen unter Ihnen, die mit dem Internet Explorer arbeiten (der keine Konsole für JavaScript hat, es sei denn, Sie öffnen die Entwicklertools mit F12und öffnen die Registerkarte "Konsole"), finden das folgende Snippet möglicherweise hilfreich. Es ermöglicht Ihnen die Verwendung
console.log(msg);
wie in den obigen Beispielen verwendet. Fügen Sie es einfach vor derPodcast
Funktion ein.Hier ist der Code oben in einem vollständigen Code-Snippet:
Code-Snippet anzeigen
Anmerkungen:
Einige gute Tipps, Hinweise und Empfehlungen zur JavaScript-Programmierung im Allgemeinen finden Sie hier (Best Practices für JavaScript) und dort ('var' versus 'let') . Empfehlenswert ist auch dieser Artikel über implizite Typografien (Zwang) .
Eine bequeme Möglichkeit, Klassen zu verwenden und sie in JavaScript zu kompilieren, ist TypeScript. Hier ist ein Spielplatz, auf dem Sie einige Beispiele finden, die Ihnen zeigen, wie es funktioniert. Auch wenn Sie momentan kein TypeScript verwenden, können Sie einen Blick darauf werfen, da Sie TypeScript nebeneinander mit dem JavaScript-Ergebnis vergleichen können. Die meisten Beispiele sind einfach, aber es gibt auch ein Raytracer-Beispiel, das Sie sofort ausprobieren können. Ich empfehle, besonders die Beispiele "Verwenden von Klassen", "Verwenden von Vererbung" und "Verwenden von Generika" zu betrachten, indem Sie sie in der Combobox auswählen - dies sind nette Vorlagen, die Sie sofort in JavaScript verwenden können. Typoskript wird mit Angular verwendet.
Um die Kapselung lokaler Variablen, Funktionen usw. in JavaScript zu erreichen, empfehle ich, ein Muster wie das folgende zu verwenden (JQuery verwendet dieselbe Technik):
Natürlich können und sollten Sie den Skriptcode in einer separaten
*.js
Datei ablegen. Dies wird nur inline geschrieben, um das Beispiel kurz zu halten.Selbstaufrufende Funktionen (auch bekannt als IIFE = Sofort aufgerufener Funktionsausdruck) werden hier ausführlicher beschrieben .
quelle
quelle
Aktualisierte Antwort:
In ECMAScript 6 können Sie statische Funktionen mit dem
static
Schlüsselwort erstellen :ES6-Klassen führen keine neue Semantik für die Statik ein. In ES5 können Sie dasselbe wie folgt tun:
Sie können einer Eigenschaft von zuweisen,
Foo
da in JavaScript Funktionen Objekte sind.quelle
Foo.bar;
Gibt die ihm zugewiesene Funktion zurück, nicht die von der Funktion zurückgegebene Zeichenfolge, wie Ihr Kommentar impliziert.bar
EigenschaftFoo
auf3
diese mag:Foo.bar = 3;
Das folgende Beispiel und die folgende Erklärung stammen aus dem Buch Professional JavaScript for Web Developers 2nd Edition von Nicholas Zakas. Dies ist die Antwort, nach der ich gesucht habe, daher dachte ich, es wäre hilfreich, sie hier hinzuzufügen.
Der
Person
Konstruktor in diesem Beispiel hat Zugriff auf den Namen der privaten Variablen, ebenso wie die MethodengetName()
undsetName()
. Bei Verwendung dieses Musters wird die Namensvariable statisch und wird in allen Instanzen verwendet. Dies bedeutet, dass der AufrufsetName()
einer Instanz alle anderen Instanzen betrifft. Durch AufrufensetName()
oder Erstellen einer neuenPerson
Instanz wird die Namensvariable auf einen neuen Wert gesetzt. Dies führt dazu, dass alle Instanzen denselben Wert zurückgeben.quelle
Wenn Sie die neue Klassensyntax verwenden , können Sie jetzt Folgendes tun:
Dadurch wird effektiv eine statische Variable in JavaScript erstellt.
quelle
MyClass
außerhalb des Klassenkonstrukts definiert.Wenn Sie statische Variablen zum Erstellen von Konstanten in Ihrer Anwendung deklarieren möchten, habe ich Folgendes als einfachsten Ansatz empfunden
quelle
Über das
class
von ECMAScript 2015 eingeführte. Die anderen Antworten sind nicht ganz klar.Hier ist ein Beispiel, das zeigt, wie eine statische Variable
staticVar
mit dem erstellt wirdClassName
.var
Synthax:Für den Zugriff auf die statische Variable verwenden wir die
.constructor
Eigenschaft, die einen Verweis auf die Objektkonstruktorfunktion zurückgibt, mit der die Klasse erstellt wurde. Wir können es auf den beiden erstellten Instanzen aufrufen:quelle
Es gibt andere ähnliche Antworten, aber keine davon hat mich wirklich angesprochen. Folgendes habe ich erreicht:
quelle
Darüber hinaus gibt es derzeit einen Entwurf ( Vorschlag der Stufe 2 ) zu ECMA-Vorschlägen , in dem
static
öffentliche Felder in Klassen eingeführt werden. ( private Felder wurden berücksichtigt )Anhand des Beispiels aus dem Vorschlag
static
sieht die vorgeschlagene Syntax folgendermaßen aus:und äquivalent zu den folgenden sein, die andere hervorgehoben haben:
Sie können dann über darauf zugreifen
CustomDate.epoch
.Sie können den neuen Vorschlag in verfolgen
proposal-static-class-features
.Derzeit unterstützt babel diese Funktion mit dem Plugin für Eigenschaften von Transformationsklassen, das Sie verwenden können. Darüber hinaus
V8
wird es implementiert , obwohl es noch in Bearbeitung ist .quelle
Sie können eine statische Variable in JavaScript wie folgt erstellen. Hier
count
ist die statische Variable.Sie können der statischen Variablen entweder mit der
Person
Funktion oder mit einer der folgenden Instanzen Werte zuweisen :quelle
Wenn Sie eine globale statische Variable erstellen möchten:
Ersetzen Sie die Variable durch die folgende:
quelle
Das, was einer statischen Variablen in JavaScript am nächsten kommt, ist eine globale Variable - dies ist einfach eine Variable, die außerhalb des Bereichs eines Funktions- oder Objektliteral deklariert ist:
Das andere, was Sie tun könnten, wäre, globale Variablen in einem Objektliteral wie folgt zu speichern:
Und dann auf die Variablen wie folgt zugreifen :
foo.bar
.quelle
Testen Sie Folgendes, um alle Klassenkonzepte hier zu verdichten:
Eine andere Möglichkeit, sich mit Best Practices in diesen Dingen zu befassen, besteht darin, zu sehen, wie Coffeescript diese Konzepte übersetzt.
quelle
In JavaScript sind Variablen standardmäßig statisch . Beispiel :
Der Wert von x wird alle 1000 Millisekunden um 1 erhöht.
Es wird 1,2,3 usw. gedruckt
quelle
Es gibt einen anderen Ansatz, der meine Anforderungen nach dem Durchsuchen dieses Threads gelöst hat. Es kommt genau darauf an, was Sie mit einer "statischen Variablen" erreichen wollen.
Mit der globalen Eigenschaft sessionStorage oder localStorage können Daten für die Dauer der Sitzung oder für einen unbestimmten längeren Zeitraum gespeichert werden, bis sie explizit gelöscht werden. Dies ermöglicht die gemeinsame Nutzung von Daten zwischen allen Fenstern, Frames, Registerkarten, Popups usw. Ihrer Seite / App und ist viel leistungsfähiger als eine einfache "statische / globale Variable" in einem Codesegment.
Es vermeidet jeglichen Ärger mit dem Umfang, der Lebensdauer, der Semantik, der Dynamik usw. globaler Variablen der obersten Ebene, dh Window.myglobal. Ich weiß nicht, wie effizient es ist, aber das ist nicht wichtig für bescheidene Datenmengen, auf die mit bescheidenen Raten zugegriffen wird.
Einfach als "sessionStorage.mydata = irgendetwas" zugegriffen und auf ähnliche Weise abgerufen. Siehe "JavaScript: The Definitive Guide, Sechste Ausgabe", David Flanagan, ISBN: 978-0-596-80552-4, Kapitel 20, Abschnitt 20.1. Dies kann einfach als PDF durch einfache Suche oder in Ihrem O'Reilly Safaribooks-Abonnement (Gold wert) heruntergeladen werden.
quelle
Funktionen / Klassen erlauben nur einen Konstruktor für ihren Objektbereich.
Function Hoisting, declarations & expressions
Verschlüsse - Verschlusskopien funktionieren mit erhaltenen Daten.
ES5-Funktionsklassen : Verwendet Object.defineProperty (O, P, Attribute)
Erstellt einige Methoden mit `` , damit jeder die Funktionsklassen leicht verstehen kann.
Das folgende Code-Snippet dient zum Testen. Jede Instanz verfügt über eine eigene Kopie von Instanzmitgliedern und allgemeinen statischen Mitgliedern.
ES6-Klassen: ES2015-Klassen sind ein einfacher Zucker über dem prototypbasierten OO-Muster. Ein einziges praktisches deklaratives Formular erleichtert die Verwendung von Klassenmustern und fördert die Interoperabilität. Klassen unterstützen prototypbasierte Vererbung, Superaufrufe, Instanz- und statische Methoden und Konstruktoren.
Beispiel : siehe meinen vorherigen Beitrag.
quelle
Es gibt 4 Möglichkeiten, funktionslokale statische Variablen in Javascript zu emulieren.
Methode 1: Verwenden von Eigenschaften von Funktionsobjekten (wird in alten Browsern unterstützt)
Methode 2: Verwenden eines Verschlusses, Variante 1 (wird in alten Browsern unterstützt)
Methode 3: Verwenden eines Verschlusses, Variante 2 (wird auch in alten Browsern unterstützt)
Methode 4: Verwenden eines Verschlusses, Variante 3 (erfordert Unterstützung für EcmaScript 2015)
quelle
Sie können statische Funktionen in JavaScript mit dem
static
Schlüsselwort definieren:Zum jetzigen Zeitpunkt können Sie noch keine statischen Eigenschaften (außer Funktionen) innerhalb der Klasse definieren. Statische Eigenschaften sind immer noch ein Vorschlag der Stufe 3 , was bedeutet, dass sie noch nicht Teil von JavaScript sind. Nichts hindert Sie jedoch daran, einfach einer Klasse zuzuweisen, wie Sie es bei jedem anderen Objekt tun würden:
Schlussbemerkung: Seien Sie vorsichtig bei der Verwendung statischer Objekte mit Vererbung. Alle geerbten Klassen verwenden dieselbe Kopie des Objekts .
quelle
In JavaScript gibt es keinen statischen Begriff oder ein statisches Schlüsselwort, aber wir können solche Daten direkt in ein Funktionsobjekt einfügen (wie in jedem anderen Objekt).
quelle
Ich benutze häufig statische Funktionsvariablen und es ist wirklich schade, dass JS dafür keinen eingebauten Mechanismus hat. Zu oft sehe ich Code, in dem Variablen und Funktionen in einem äußeren Bereich definiert sind, obwohl sie nur in einer Funktion verwendet werden. Das ist hässlich, fehleranfällig und bittet nur um Ärger ...
Ich habe mir folgende Methode ausgedacht:
Dies fügt allen Funktionen eine 'statische' Methode hinzu (ja, entspannen Sie sich einfach). Wenn sie aufgerufen wird, fügt sie dem Funktionsobjekt ein leeres Objekt (_statics) hinzu und gibt es zurück. Wenn eine Init-Funktion bereitgestellt wird, wird _statics auf init () result gesetzt.
Sie können dann tun:
Wenn man dies mit einem IIFE vergleicht, das die andere richtige Antwort ist, hat dies den Nachteil, dass bei jedem Funktionsaufruf eine Zuweisung und eine hinzugefügt wird, wenn der Funktion ein '_statics'-Mitglied hinzugefügt wird. Es gibt jedoch einige Vorteile: Die Argumente sind da bei Das oberste nicht in der internen Funktion, die Verwendung eines 'statischen' im internen Funktionscode ist explizit mit einem '_s'. Präfix, und es ist insgesamt einfacher zu betrachten und zu verstehen.
quelle
Zusammenfassung:
In
ES6
/ ES 2015 wurde dasclass
Schlüsselwort mit einem begleitendenstatic
Schlüsselwort eingeführt. Denken Sie daran, dass dies syntaktischer Zucker gegenüber dem prototypischen Vererbungsmodell ist, das Javavscript verkörpert. Dasstatic
Schlüsselwort funktioniert für Methoden folgendermaßen:quelle
Ich habe den Prototyp verwendet und so hat es funktioniert:
oder mit einem statischen Getter:
quelle
Vars auf Fensterebene sind in dem Sinne statisch, dass Sie eine direkte Referenz verwenden können und diese für alle Teile Ihrer App verfügbar sind
quelle
In Javascript gibt es keine statische Variable. Diese Sprache ist prototypbasiert objektorientiert, daher gibt es keine Klassen, sondern Prototypen, von denen Objekte sich selbst "kopieren".
Sie können sie mit globalen Variablen oder mit Prototyping simulieren (dem Prototyp eine Eigenschaft hinzufügen):
quelle
Function.prototype
function circle() {}
|circle.prototype
|circle.prototype.pi = 3.14
|circle.prototype
|Function.prototype
|Function.__proto__
(Wenn Sie das gemeint haben)Bei der Arbeit mit MVC-Websites, die jQuery verwenden, möchte ich sicherstellen, dass AJAX-Aktionen in bestimmten Ereignishandlern erst ausgeführt werden können, wenn die vorherige Anforderung abgeschlossen wurde. Ich benutze eine "statische" jqXHR-Objektvariable, um dies zu erreichen.
Gegeben die folgende Schaltfläche:
Im Allgemeinen verwende ich ein solches IIFE für meinen Klick-Handler:
quelle
Wenn Sie einen Prototyp verwenden möchten, gibt es einen Weg
Auf diese Weise können Sie von jeder Instanz aus auf die Zählervariable zugreifen und jede Änderung der Eigenschaft wird sofort wiedergegeben !!
quelle