Ich habe das Thema über "neues" Schlüsselwort in Javascript gelesen ( Was? ist das 'neue' Schlüsselwort in JavaScript? ). Aber ich bin immer noch im Nebel; Lass uns über dieses Beispiel sprechen:
%Vor%Und nun, was ist mit diesen zwei Teilen des Codes:
Eins:
%Vor%Zwei:
%Vor%Ich kann auf meinem Niveau keine Unterschiede sehen. Also, was ist der Gewinn, um das Schlüsselwort "neu" zu verwenden?
Wenn Ihre Funktion das Objekt direkt zurückgibt, benötigen Sie keinen new
-Operator.
Die Tasten new
machen mehr als das.
Sagen wir
%Vor%Dann machst du
%Vor%Javascript Engine wird folgende Dinge tun
%Vor% Object.create
übernimmt die Prototypvererbung des prototype
-Objekts von Animal
function. Also hat animal
object seine eigenen Eigenschaften und seine geerbte Eigenschaft.
Ich bin immer noch im Nebel über
%Vor%new
; Lass uns über dieses Beispiel sprechen:
Wir sollten nicht über dieses Beispiel sprechen. Ob wir new
mit dieser Funktion verwenden oder nicht, macht keinen Unterschied, weil wie new
funktioniert :
- Ein neues Objekt wird erstellt, das von
erbtfoo.prototype
.- Die Konstruktorfunktion
foo
wird mit den angegebenen Argumenten und % co_de aufgerufen % gebunden zu das neu erstellte Objekt.- Das von der Konstruktorfunktion zurückgegebene Objekt wird zum Ergebnis von dem ganzen neuen Ausdruck. Wenn die Konstruktorfunktion dies nicht tut explizit ein Objekt zurückgeben, wird das in Schritt 1 erstellte Objekt verwendet stattdessen. (Normalerweise geben Konstruktoren keinen Wert zurück, aber sie können Wählen Sie dies, wenn Sie die normale Objekterstellung überschreiben möchten Prozess.)
Schritt 3 ist die Sache, die hier zu sehen ist. Sie erstellen ein Objekt (das Objektliteral) und geben es zurück, sodass es this
zugewiesen wird. Normalerweise haben Konstruktorfunktionen nicht bob1
nichts, und die neue Instanz, die implizit in Schritt 1 erstellt wurde (und innerhalb der Funktion als return
verfügbar ist), wird zum Ergebnis.
Sowohl this
als auch new foo()
weisen Ihr Objektliteral nur der Variablen foo()
zu - kein Unterschied im Ergebnis. Die von bob
erstellte Instanz wird von Ihrem Code vollständig ignoriert. In den folgenden Beispielen wäre das anders:
Wenn die Konstruktorfunktion foo
ein Objekt zurückgibt, dann ist new foo()
identisch mit dem Aufruf der Funktion foo()
direkt. Dies können wir nachweisen, indem wir das ECMAScript-Verhalten für new
untersuchen :
Gibt das Ergebnis des Aufrufs der internen Methode [[Construct]] für -Konstruktor zurück [d. h. die Konstruktorfunktion] ...
Die [[Construct]]
interne Methode einer Funktion ist eine Besonderheit Wrapper zum Aufrufen der internen Methode [[Call]]
der Funktion (dies ist nur das normale Verhalten der Funktion). Lassen Sie uns das Ende von [[Construct]]
sehen, um zu sehen, wie sich dieser Wrapper verhält:
8) Ergebnis sei das Ergebnis des Aufrufs der internen [[Call]] - Eigenschaft von F [die von
new
] aufgerufene Funktion, die bereitstellt obj alsthis
-Wert und stellt die Argumentliste in [[Construct]] als Argument bereit.9) Wenn Type ( result ) Objekt ist, dann gebe result zurück.
10) Geben Sie obj zurück.
In Ihrem Fall gibt Ihre Konstruktorfunktion foo
ein Objekt zurück, so dass Schritt 9 von [[Construct]]
(und damit wiederum new foo()
) dieses Objekt zurückgibt. Aber wir sehen in Schritt 10, dass [[Construct]]
einen anderen Wert namens obj zurückgeben kann, der gleich dem this
-Wert innerhalb des Konstruktors ist. Lassen Sie uns zurückspulen und sehen, worum es geht:
1) obj sei ein neu erstelltes natives ECMAScript-Objekt.
...
4) Geben Sie proto als Wert für den Aufruf der internen Eigenschaft [[Get]] von F mit dem Argument "
prototype
" an.5) Wenn Type ( proto ) Objekt ist, setzen Sie die interne Eigenschaft [[Prototyp]] von obj auf proto .
Hier sehen wir die wirkliche Potenz von new
: Wenn die Konstruktorfunktion kein Objekt zurückgibt (und daher die von [[Construct]]
gestartete new
-Operation obj
zurückgeben darf), findet eine prototypische Vererbung statt . Die [[Prototype]]
von obj
(a.k.a. obj.__proto__
) wird auf die Eigenschaft prototype
der Konstruktormethode gesetzt. Das bedeutet, wenn foo
kein Objekt zurückgibt (und stattdessen this
ändert) und foo.prototype.someProp
gesetzt ist, hat eine von var instance = new foo()
zurückgegebene Instanz Zugriff auf instance.someProp
.
Daher könnte Ihr Code anders geschrieben werden:
%Vor% In diesem Fall erzeugt new foo()
ein Objekt, dessen Prototypkette foo.prototype
enthält, während foo()
dies nicht tut. Dies hat den Vorteil geringerer Speicherauslastung: Alle foo
Instanzen teilen sich hier gemeinsame prototypische Methoden, anstatt jede Instanz eigene Funktionen zu haben.
Tags und Links javascript object