Ich habe vor einiger Zeit einen leeren Stub auf MDN für das Reflect
Objekt in Javascript gesehen, aber ich kann für mein ganzes Leben nichts bei Google finden. Heute habe ich dieses http://people.mozilla.org/~jorendorff/es6-draft.html#sec-reflect-object gefunden und es klingt ähnlich wie das Proxy-Objekt, abgesehen von der Realm- und Loader-Funktionalität.
Grundsätzlich weiß ich nicht, ob diese Seite, die ich gefunden habe, nur die Implementierung von Reflect erklärt oder ob ich den Wortlaut einfach nicht verstehen kann. Könnte mir bitte jemand allgemein erklären, wie die Methoden Reflect
aussehen?
Auf der Seite, die ich gefunden habe, heißt es beispielsweise, dass der Aufruf Reflect.apply ( target, thisArgument, argumentsList )
"das Ergebnis des Aufrufs der internen Zielmethode [[Call]] mit den Argumenten thisArgument und args zurückgibt". aber wie ist das anders als nur anzurufen target.apply(thisArgument, argumentsList)
?
Aktualisieren:
Dank @Blue fand ich diese Seite im Wiki
http://wiki.ecmascript.org/doku.php?id=harmony:reflect_api&s=reflect,
das nach meinem besten Wissen besagt, dass das Reflect-Objekt Methodenversionen von allen bereitstellt die Aktionen, die von Proxys abgefangen werden können, um die Weiterleitung zu vereinfachen. Aber das kommt mir etwas komisch vor, da ich nicht sehe, wie notwendig es ist. Aber es scheint ein wenig mehr zu tun, insbesondere das Par, das sagt, double-lifting
aber das auf die alte Proxy-Spezifikation hinweist /
quelle
Reflect
ist es nur ein Container fürRealm
undLoader
Objekte, aber ich weiß auch nicht, was letztere tun.Reflect.Loader
undReflect.Realm
etwas mit Überlastung Modulfunktionalität zu tun haben?isExtensible
,ownKeys
usw. ES 6, mit dem tatsächlichen Klassen, dies nützlich mehr über eine Klasse , um herauszufinden , (target
in 16.1.2 glaube ich).Antworten:
UPDATE 2015: Wie aus der Antwort von 7th hervorgeht , ist nach Abschluss von ES6 (ECMAScript 2015) eine geeignetere Dokumentation verfügbar:
Ursprüngliche Antwort (für (historisches) Verständnis und zusätzliche Beispiele) :
Der
Reflection proposal
scheint zum Entwurf der ECMAScript 6-Spezifikation übergegangen zu sein . Dieses Dokument beschreibt derzeit dieReflect
Methoden des Objekts und gibt nur Folgendes über dasReflect
Objekt selbst an:Es gibt jedoch eine kurze Erklärung zu seinem Zweck in ES Harmony :
Daher bietet das
Reflect
Objekt eine Reihe von Dienstprogrammfunktionen, von denen sich viele mit den im globalen Objekt definierten ES5-Methoden zu überschneiden scheinen.Dies erklärt jedoch nicht wirklich, welche vorhandenen Probleme dadurch gelöst werden sollen oder welche Funktionen hinzugefügt werden. Ich vermutete, dass dies abgeglichen werden könnte, und tatsächlich verweist die obige Harmonie-Spezifikation auf eine „nicht normative, ungefähre Implementierung dieser Methoden“ .
Das Untersuchen dieses Codes könnte (weitere) Ideen über seine Verwendung geben, aber zum Glück gibt es auch ein Wiki, das eine Reihe von Gründen aufzeigt, warum das Reflect-Objekt nützlich ist :
(Ich habe den folgenden Text kopiert (und formatiert), um später darauf zurückgreifen zu können Quelle, da sie die einzigen Beispiele sind, die ich finden konnte. Außerdem sind sie sinnvoll, haben bereits eine gute Erklärung und berühren das
apply
Beispiel der Frage .)Weitere nützliche Rückgabewerte
Viele Operationen in
Reflect
ähneln den auf definierten ES5-OperationenObject
wieReflect.getOwnPropertyDescriptor
undReflect.defineProperty
. WährendObject.defineProperty(obj, name, desc)
jedoch entweder zurückgegeben wird,obj
wenn die Eigenschaft erfolgreich definiert wurde, oder einTypeError
anderesReflect.defineProperty(obj, name, desc)
ausgelöst wird, wird nur ein Boolescher Wert zurückgegeben, der angibt, ob die Eigenschaft erfolgreich definiert wurde oder nicht. Auf diese Weise können Sie diesen Code umgestalten:Dazu:
Andere Methoden, die einen solchen booleschen Erfolgsstatus zurückgeben, sind
Reflect.set
(um eine Eigenschaft zu aktualisieren),Reflect.deleteProperty
(um eine Eigenschaft zu löschen),Reflect.preventExtensions
(um ein Objekt nicht erweiterbar zu machen) undReflect.setPrototypeOf
(um die Prototypverknüpfung eines Objekts zu aktualisieren).Erstklassiger Betrieb
In ES5 können Sie feststellen, ob ein Objekt
obj
einen bestimmten Eigenschaftsnamen definiert oder erbt(name in obj)
. Ebenso verwendet man zum Löschen einer Eigenschaftdelete obj[name]
. Die dedizierte Syntax ist zwar nett und kurz, bedeutet aber auch, dass Sie diese Operationen explizit in Funktionen einschließen müssen, wenn Sie die Operation als erstklassigen Wert weitergeben möchten.Mit
Reflect
können diese Operationen leicht als erstklassige Funktionen definiert werden:Reflect.has(obj, name)
ist das funktionale Äquivalent von(name in obj)
undReflect.deleteProperty(obj, name)
ist eine Funktion, die dasselbe tut wiedelete obj[name].
Zuverlässigere Funktionsanwendung
Wenn man in ES5 eine Funktion
f
mit einer variablen Anzahl von Argumenten aufrufen möchte, die als Array gepackt sindargs
und an die derthis
Wert gebunden istobj
, kann man schreiben:Könnte
f
jedoch ein Objekt sein, das absichtlich oder unbeabsichtigt seine eigeneapply
Methode definiert . Wenn Sie wirklich sicherstellen möchten, dass die integrierteapply
Funktion aufgerufen wird, schreibt man normalerweise:Dies ist nicht nur ausführlich, es wird auch schnell schwer zu verstehen. Mit
Reflect
können Sie jetzt einen zuverlässigen Funktionsaufruf kürzer und verständlicher durchführen:Konstruktoren mit variablen Argumenten
Stellen Sie sich vor, Sie möchten eine Konstruktorfunktion mit einer variablen Anzahl von Argumenten aufrufen. In ES6 ist es dank der neuen Spread-Syntax möglich, Code wie folgt zu schreiben:
In ES5 ist dies schwieriger zu schreiben, da nur eine Funktion mit einer variablen Anzahl von Argumenten verwendet
F.apply
oderF.call
aufgerufen werden kann, die Funktion mit einer variablen Anzahl von Argumenten jedoch keineF.construct
Funktion hatnew
. MitReflect
kann man jetzt in ES5 schreiben:Standardweiterleitungsverhalten für Proxy-Traps
Wenn Sie
Proxy
Objekte verwenden, um vorhandene Objekte zu verpacken, ist es sehr üblich, eine Operation abzufangen, etwas zu tun und dann "die Standardeinstellung" auszuführen, bei der die abgefangene Operation normalerweise auf das umschlossene Objekt angewendet wird. Angenommen, ich möchte einfach alle Eigenschaftszugriffe auf ein Objekt protokollierenobj
:Die
Reflect
undProxy
APIs wurden zusammen entworfen , sodass für jedeProxy
Falle eine entsprechende Methode vorhanden istReflect
, die "die Standardeinstellung ausführt". Wenn Sie also feststellen, dass Sie die Standardeinstellung in einem Proxy-Handler ausführen möchten, müssen Sie immer die entsprechende Methode imReflect
Objekt aufrufen :Der Rückgabetyp der
Reflect
Methoden ist garantiert mit dem Rückgabetyp derProxy
Traps kompatibel .Kontrollieren Sie diese Bindung von Accessoren
In ES5 ist es ziemlich einfach, einen allgemeinen Eigenschaftszugriff oder eine Eigenschaftsaktualisierung durchzuführen. Zum Beispiel:
Mit den Methoden
Reflect.get
undReflect.set
können Sie dasselbe tun, aber zusätzlich als letztes optionales Argument einenreceiver
Parameter akzeptieren , mit dem Sie diethis
Bindung explizit festlegen können, wenn die Eigenschaft, die Sie erhalten / festlegen, ein Accessor ist:Dies ist gelegentlich nützlich, wenn Sie einpacken
obj
und möchten, dass alle Selbstsendungen innerhalb des Accessors an Ihren Wrapper weitergeleitet werden, z. B. wenn Folgendesobj
definiert ist:Durch einen Anruf
Reflect.get(obj, "foo", wrapper)
wird derthis.bar()
Anruf umgeleitetwrapper
.Vermeiden Sie Vermächtnis
__proto__
Wird in einigen Browsern
__proto__
als spezielle Eigenschaft definiert, die den Zugriff auf den Prototyp eines Objekts ermöglicht. ES5 standardisierte eine neue MethodeObject.getPrototypeOf(obj)
zur Abfrage des Prototyps.Reflect.getPrototypeOf(obj)
macht genau das gleiche, außer dassReflect
auch ein entsprechender definiert wirdReflect.setPrototypeOf(obj, newProto)
, um den Prototyp des Objekts festzulegen. Dies ist die neue ES6-kompatible Methode zum Aktualisieren des Prototyps eines Objekts.Beachten Sie, dass:
setPrototypeOf
auch vorhanden aufObject
(wie korrekt darauf hingewiesen Knu ‚s Kommentar )!BEARBEITEN:
Randnotiz (Adressieren von Kommentaren zum Q): Es gibt eine kurze und einfache Antwort zu 'Q: ES6-Module vs. HTML-Importe' , die erklärt
Realms
undLoader
Objekte.Eine weitere Erklärung bietet dieser Link :
Erwähnenswert:
All dies ist noch im Entwurf, dies ist keine in Stein gemeißelte Spezifikation!Es ist ES6, denken Sie also an die Browserkompatibilität!Hoffe das hilft!
quelle
Reflect.apply
und zusammenhängttarget.apply
? Oder was soll ich hinzufügen, bevor das Kopfgeld endet?Object
.Reflect.get
als Standardimplementierung für Proxy-Get nicht gut funktioniert, wenn Sie ein Objekt mit Prototyp-Eigenschaften als Proxy verwenden. Es beschwert sich nur, dass es nicht funktioniert. Wenn Sie jedoch stattdessen verwenden,Reflect.get(target, property)
ohne das zu übergebenreceiver
, funktioniert es.target
das ursprüngliche Ziel ist, das der Proxy umschließt, währendreceiver
der Proxy selbst ist. Dies kann jedoch auch anders sein, wenn Sie anders auf die Eigenschaften zugreifen können.Nach dem Entwurf des Dokuments im Wiki,
http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts
Wir erhalten die Zeile über "einzelnes gewöhnliches Objekt", die im Entwurf klargestellt wird. Es hat auch die Funktionsdefinitionen.
Das Wiki sollte zuverlässig sein, da Sie auf der Emcascript-Website einen Link dazu finden
http://www.ecmascript.org/dev.php
Ich habe den ersten Link von Google gefunden und hatte kein Glück, ihn durch direktes Durchsuchen des Wikis zu finden.
quelle