Das new
Schlüsselwort in JavaScript kann beim ersten Auftreten ziemlich verwirrend sein, da die Leute glauben, dass JavaScript keine objektorientierte Programmiersprache ist.
- Was ist es?
- Welche Probleme löst es?
- Wann ist es angebracht und wann nicht?
javascript
new-operator
Alon Gubkin
quelle
quelle
Antworten:
Es macht 5 Dinge:
this
Variable zeigt auf das neu erstellte Objekt.this
immer dies erwähnt wird.null
Objektreferenz zurück. In diesem Fall wird stattdessen diese Objektreferenz zurückgegeben.Hinweis: Die Konstruktorfunktion bezieht sich auf die Funktion nach dem
new
Schlüsselwort wie inSobald dies erledigt ist und eine undefinierte Eigenschaft des neuen Objekts angefordert wird, überprüft das Skript stattdessen das [[Prototyp]] - Objekt des Objekts auf die Eigenschaft. Auf diese Weise können Sie etwas Ähnliches wie bei der herkömmlichen Klassenvererbung in JavaScript erhalten.
Der schwierigste Teil dabei ist Punkt Nummer 2. Jedes Objekt (einschließlich Funktionen) hat diese interne Eigenschaft namens [[Prototyp]] . Sie kann nur zum Zeitpunkt der Objekterstellung festgelegt werden, entweder mit new , mit Object.create oder basierend auf dem Literal (Funktionen standardmäßig Function.prototype, Zahlen to Number.prototype usw.). Es kann nur mit Object.getPrototypeOf (someObject) gelesen werden . Es gibt keine andere Möglichkeit, diesen Wert festzulegen oder zu lesen.
Funktionen verfügen neben der Eigenschaft hidden [[prototype]] auch über eine Eigenschaft namens prototype . Auf diese Eigenschaft können Sie zugreifen und Änderungen vornehmen, um geerbte Eigenschaften und Methoden für die von Ihnen erstellten Objekte bereitzustellen.
Hier ist ein Beispiel:
Es ist wie bei der Klassenvererbung, da jetzt alle Objekte, die Sie verwenden
new ObjMaker()
, anscheinend auch die Eigenschaft 'b' geerbt haben.Wenn Sie so etwas wie eine Unterklasse wollen, dann tun Sie dies:
Ich habe eine Menge Müll zu diesem Thema gelesen, bevor ich endlich diese Seite gefunden habe , auf der dies sehr gut mit schönen Diagrammen erklärt wird.
quelle
ObjMaker
es sich um eine Funktion handelt, die einen Wert zurückgibt?new
vorhanden, sodass Sie keine Factory-Methoden schreiben müssen, um Funktionen / Objekte zu erstellen / kopieren. Es bedeutet: "Kopieren Sie dies so, dass es genau wie die übergeordnete 'Klasse' ist. Tun Sie dies effizient und korrekt. Speichern Sie Vererbungsinformationen, auf die nur ich, JS, intern zugreifen kann." Zu diesem Zweck wird das ansonsten unzugängliche Innereprototype
des neuen Objekts so geändert, dass die geerbten Mitglieder undurchsichtig gekapselt werden, wodurch klassische OO-Vererbungsketten nachgeahmt werden (die zur Laufzeit nicht modifizierbar sind). Sie können dies ohne simulierennew
, aber die Vererbung kann zur Laufzeit geändert werden. Gut? Schlecht? Wie du willst.Notice that this pattern is deprecated!
. Was ist das richtige aktuelle Muster, um den Prototyp einer Klasse festzulegen?Angenommen, Sie haben diese Funktion:
Wenn Sie dies als eigenständige Funktion wie folgt aufrufen:
Durch Ausführen dieser Funktion werden dem
window
Objekt (A
undB
) zwei Eigenschaften hinzugefügt . Es fügt es hinzu,window
weilwindow
es das Objekt ist, das die Funktion aufgerufen hat, wenn Sie es so ausführen, undthis
in einer Funktion das Objekt, das die Funktion aufgerufen hat. Zumindest in Javascript.Nennen Sie es jetzt so mit
new
:Wenn Sie
new
einem Funktionsaufruf hinzufügen , wird ein neues Objekt (nurvar bar = new Object()
) erstellt und dasthis
innerhalb der Funktion zeigt auf dasObject
gerade erstellte neue Objekt anstatt auf das Objekt, das die Funktion aufgerufen hat. Sobar
ist nun ein Objekt mit den EigenschaftenA
undB
. Jede Funktion kann ein Konstruktor sein, es macht einfach nicht immer Sinn.quelle
window
implizite Methode . Auch in einer Schließung, auch wenn anonymus. Im Beispiel handelt es sich jedoch um einen einfachen Methodenaufruf im Fenster:Foo();
=>[default context].Foo();
=>window.Foo();
. In diesem Ausdruckwindow
steht der Kontext (nicht nur der Anrufer , der keine Rolle spielt).Zusätzlich zu Daniel Howards Antwort ist hier, was
new
tut (oder zumindest zu tun scheint):Während
ist äquivalent zu
quelle
func.prototype
zu seinnull
? Könnten Sie bitte etwas näher darauf eingehen?A.prototype = null;
In diesem Fallnew A()
führt dies zu einem Objekt, dessen interner Prototyp auf dasObject
Objekt zeigt: jsfiddle.net/Mk42ZObject(ret) === ret
.typeof
Test für diese konzeptionelle Antwort es einfacher macht zu verstehen, was sich hinter den Kulissen abspielt.Für Anfänger, um es besser zu verstehen
Probieren Sie den folgenden Code in der Browserkonsole aus.
Jetzt kannst du die Antwort des Community-Wikis lesen :)
quelle
return this;
ergibt die gleiche Leistung.Es wird genau dafür verwendet. Sie definieren einen Funktionskonstruktor wie folgt:
Der zusätzliche Vorteil von ECMAScript besteht jedoch darin, dass Sie die
.prototype
Eigenschaft erweitern können, sodass wir so etwas wie ...Alle Objekte, die mit diesem Konstruktor erstellt wurden, haben jetzt
getName
aufgrund der Prototypkette, auf die sie Zugriff haben, eine.quelle
class
Schlüsselwort, aber Sie können so ziemlich das Gleiche tun.JavaScript ist eine objektorientierte Programmiersprache und wird genau zum Erstellen von Instanzen verwendet. Es basiert eher auf Prototypen als auf Klassen, aber das bedeutet nicht, dass es nicht objektorientiert ist.
quelle
Javascript ist eine dynamische Programmiersprache, die das objektorientierte Programmierparadigma unterstützt und zum Erstellen neuer Objektinstanzen verwendet wird.
Klassen sind für Objekte nicht erforderlich - Javascript ist eine prototypbasierte Sprache.
quelle
Es gibt bereits einige sehr gute Antworten, aber ich veröffentliche eine neue, um meine Beobachtung zu Fall III unten zu betonen, was passiert, wenn Sie eine explizite return-Anweisung in einer Funktion haben, die Sie gerade
new
erstellen. Schauen Sie sich die folgenden Fälle an:Fall I :
Oben sehen Sie einen einfachen Fall, in dem die anonyme Funktion aufgerufen wird, auf die verwiesen wird
Foo
. Wenn Sie diese Funktion aufrufen, wird sie zurückgegebenundefined
. Da es keine explizite return-Anweisung gibt, fügt der JavaScript-Interpreter einereturn undefined;
Anweisung am Ende der Funktion zwangsweise ein . Hier ist das Fenster das Aufrufobjekt (kontextbezogenthis
), das neuA
undB
Eigenschaften erhält .Fall II :
Hier
new
erstellt ein JavaScript-Interpreter, der das Schlüsselwort sieht, ein neues Objekt, das als Aufrufobjekt (kontextbezogenthis
) einer anonymen Funktion fungiert, auf die verwiesen wirdFoo
. In diesem FallA
undB
wurden Eigenschaften für das neu erstellte Objekt (anstelle von Fenster - Objekt). Da Sie keine explizite return-Anweisung haben, fügt der JavaScript-Interpreter eine return-Anweisung zwangsweise ein, um das neue Objekt zurückzugeben, das aufgrund der Verwendung desnew
Schlüsselworts erstellt wurde.Fall III :
Auch hier erstellt der JavaScript-Interpreter, der das
new
Schlüsselwort sieht, ein neues Objekt, das als Aufrufobjekt (kontextbezogenthis
) einer anonymen Funktion fungiert, auf die verwiesen wirdFoo
. WiederA
undB
werden Eigenschaften für das neu erstellte Objekt. Aber dieses Mal , wenn Sie eine explizite Anweisung return haben , so wird JavaScript - Interpreter nicht alles von selbst tun.In Fall III ist zu beachten, dass das Objekt, das aufgrund eines
new
Schlüsselworts erstellt wurde, von Ihrem Radar verloren gegangen ist.bar
zeigt tatsächlich auf ein völlig anderes Objekt, das nicht das ist, das der JavaScript-Interpreter aufgrund einesnew
Schlüsselworts erstellt hat.Zitiert David Flanagan aus JavaScripit: The Definitive Guide (6. Ausgabe), Kap. 4, Seite 62:
--- Zusätzliche Informationen ---
Die im Code-Snippet der oben genannten Fälle verwendeten Funktionen haben in der JS-Welt folgende spezielle Namen:
Fall I und II - Konstruktorfunktion
Fall III - Werksfunktion. Factory-Funktionen sollten nicht mit
new
Schlüsselwörtern verwendet werden, mit denen ich das Konzept im aktuellen Thread erklärt habe.In diesem Thread können Sie den Unterschied zwischen ihnen nachlesen .
quelle
Manchmal ist Code einfacher als Worte:
Solange ich kein Prototyp bin, verwende ich für mich den Stil von func2, da er mir innerhalb und außerhalb der Funktion ein bisschen mehr Flexibilität gibt.
quelle
B1 = new func2(2);
<- Warum wird das nicht habenB1.y
?Das
new
Schlüsselwort ändert den Kontext, unter dem die Funktion ausgeführt wird, und gibt einen Zeiger auf diesen Kontext zurück.Wenn Sie das
new
Schlüsselwort nicht verwenden , ist der Kontext, unter dem die Funktion ausgeführtVehicle()
wird, derselbe Kontext, aus dem Sie dieVehicle
Funktion aufrufen . Dasthis
Schlüsselwort verweist auf denselben Kontext. Bei Verwendungnew Vehicle()
wird ein neuer Kontext erstellt, sodass das Schlüsselwortthis
in der Funktion auf den neuen Kontext verweist. Als Gegenleistung erhalten Sie den neu erstellten Kontext.quelle
Das
new
Schlüsselwort dient zum Erstellen neuer Objektinstanzen. Und ja, Javascript ist eine dynamische Programmiersprache, die das objektorientierte Programmierparadigma unterstützt. Die Konvention über die Objektbenennung lautet: Verwenden Sie immer Großbuchstaben für Objekte, die durch das neue Schlüsselwort instanziiert werden sollen.quelle
Zusammenfassung:
Das
new
Schlüsselwort wird in Javascript verwendet, um ein Objekt aus einer Konstruktorfunktion zu erstellen. Dasnew
Schlüsselwort muss vor dem Konstruktorfunktionsaufruf stehen und führt folgende Aktionen aus:this
Schlüsselwort an das neu erstellte Objekt und führt die Konstruktorfunktion ausBeispiel:
Was genau passiert:
const doggie
sagt: Wir brauchen Speicher zum Deklarieren einer Variablen.=
sagt: Wir werden diese Variable mit dem Ausdruck nach dem initialisieren=
new Dog(12)
. Die JS-Engine erkennt das neue Schlüsselwort, erstellt ein neues Objekt und setzt den Prototyp auf Dog.prototypethis
auf das neue Objekt festgelegten Wert . In diesem Schritt wird das Alter dem neu erstellten Hundeobjekt zugewiesen.quelle
Das
new
Schlüsselwort erstellt Instanzen von Objekten mithilfe von Funktionen als Konstruktor. Zum Beispiel:Instanzen erben von
prototype
der Konstruktorfunktion. Also angesichts des obigen Beispiels ...quelle
Nun, JavaScript per si kann von Plattform zu Plattform sehr unterschiedlich sein, da es immer eine Implementierung der ursprünglichen Spezifikation EcmaScript ist.
Unabhängig von der Implementierung erhalten Sie in jedem Fall alle JavaScript-Implementierungen, die der EcmaScript-Spezifikation entsprechen, eine objektorientierte Sprache. Nach dem ES-Standard:
Nachdem wir uns darauf geeinigt haben, dass JavaScript eine Implementierung von EcmaScript und daher eine objektorientierte Sprache ist. Die Definition der
new
Operation in einer objektorientierten Sprache besagt, dass ein solches Schlüsselwort verwendet wird, um eine Objektinstanz aus einer Klasse eines bestimmten Typs (einschließlich anonymer Typen in Fällen wie C #) zu erstellen.In EcmaScript verwenden wir keine Klassen, wie Sie aus den Spezifikationen lesen können:
quelle