Warum wurde die arguments.callee.caller
Eigenschaft in JavaScript nicht mehr unterstützt?
Es wurde hinzugefügt und dann in JavaScript veraltet, aber von ECMAScript insgesamt weggelassen. Einige Browser (Mozilla, IE) haben dies immer unterstützt und haben keine Pläne auf der Karte, die Unterstützung zu entfernen. Andere (Safari, Opera) haben Unterstützung dafür übernommen, aber die Unterstützung in älteren Browsern ist unzuverlässig.
Gibt es einen guten Grund, diese wertvolle Funktionalität in die Schwebe zu bringen?
(Oder gibt es alternativ eine bessere Möglichkeit, die aufrufende Funktion in den Griff zu bekommen?)
javascript
ecma262
pcorcoran
quelle
quelle
<b>
und kamen wir<i>
zurück (ja, diese waren an einem Punkt veraltet).Antworten:
Frühere Versionen von JavaScript erlaubten keine benannten Funktionsausdrücke, und aus diesem Grund konnten wir keinen rekursiven Funktionsausdruck erstellen:
Um dies zu umgehen,
arguments.callee
wurde hinzugefügt, damit wir Folgendes tun können:Dies war jedoch tatsächlich eine wirklich schlechte Lösung, da dies (in Verbindung mit anderen Argumenten, Angerufenen und Anruferproblemen) das Inlining und die Schwanzrekursion im allgemeinen Fall unmöglich macht (Sie können dies in ausgewählten Fällen durch Nachverfolgung usw. erreichen, aber auch durch den besten Code ist aufgrund von Prüfungen, die sonst nicht notwendig wären, suboptimal). Das andere Hauptproblem ist, dass der rekursive Aufruf einen anderen
this
Wert erhält, zum Beispiel:Wie auch immer, EcmaScript 3 hat diese Probleme gelöst, indem benannte Funktionsausdrücke zugelassen wurden, z.
Dies hat zahlreiche Vorteile:
Die Funktion kann wie jede andere in Ihrem Code aufgerufen werden.
Der Namespace wird nicht verschmutzt.
Der Wert von
this
ändert sich nicht.Es ist performanter (der Zugriff auf das Argumentobjekt ist teuer).
Hoppla,
Ich habe gerade festgestellt, dass es neben allem anderen um die Frage ging
arguments.callee.caller
, genauer gesagtFunction.caller
.Zu jedem Zeitpunkt können Sie den tiefsten Aufrufer einer Funktion auf dem Stapel finden, und wie ich oben sagte, hat das Betrachten des Aufrufstapels einen einzigen Haupteffekt: Es macht eine große Anzahl von Optimierungen unmöglich oder viel schwieriger.
Z.B. Wenn wir nicht garantieren können, dass eine Funktion
f
keine unbekannte Funktion aufruft, kann nicht inline geschaltet werdenf
. Grundsätzlich bedeutet dies, dass jede Anrufstelle, die möglicherweise trivial inlinierbar war, eine große Anzahl von Wachen ansammelt. Nehmen Sie:Wenn der js-Interpreter zum Zeitpunkt des Aufrufs nicht garantieren kann, dass alle angegebenen Argumente Zahlen sind, muss er entweder vor dem Inline-Code Überprüfungen für alle Argumente einfügen oder die Funktion nicht einbinden.
In diesem speziellen Fall sollte ein intelligenter Interpreter in der Lage sein, die Prüfungen neu anzuordnen, um sie optimaler zu gestalten, und keine Werte zu prüfen, die nicht verwendet würden. In vielen Fällen ist dies jedoch einfach nicht möglich und daher wird es unmöglich, Inline zu erstellen.
quelle
this
daher denke ich, dass es für die Frage, ob Angerufene gut oder schlecht sind, irrelevant ist. Außerdem sind Angerufene und Anrufer nur im strengen Modus "veraltet" (ECMAscript ed 5, Dec 2009), aber ich denke, das war 2008 nicht bekannt, als olliej gepostet hat.this
ifthis
als globaler Bereich erhalten. In allen anderen Fällen wird der Wertthis
wird nach dem ersten rekursiven Aufruf ändern, so dass ich die Teile Ihrer Antwort denken , auf die Erhaltung anspielend vonthis
nicht wirklich gültig sind.arguments.callee.caller
ist nicht veraltet, obwohl es die Eigenschaft nutzt . ( gibt Ihnen nur einen Verweis auf die aktuelle Funktion)Function.caller
arguments.callee
Function.caller
Obwohl gemäß ECMA3 nicht standardisiert, ist es in allen gängigen Hauptbrowsern implementiert .arguments.caller
wird zugunsten von abgelehnt und ist in einigen aktuellen Hauptbrowsern (z. B. Firefox 3) nicht implementiert.Function.caller
Die Situation ist also nicht ideal, aber wenn Sie über alle gängigen Browser auf die aufrufende Funktion in Javascript zugreifen möchten, können Sie die Eigenschaft verwenden, auf die entweder direkt über eine benannte Funktionsreferenz oder über die Eigenschaft innerhalb einer anonymen Funktion zugegriffen wird .
Function.caller
arguments.callee
quelle
arguments.callee
jedoch im strengen Modus verboten. Es hat mich auch traurig gemacht, aber es ist besser, es nicht mehr zu benutzen.arguments.callee.caller
im strengen ES5-Modus veraltet ist: "Eine weitere Funktion, die nicht mehr unterstützt wurde, war argument.callee.caller oder genauer Function.caller." ( Quelle )Es ist besser, benannte Funktionen als Argumente zu verwenden.
ist besser als
Die benannte Funktion hat über die Caller- Eigenschaft Zugriff auf ihren Aufrufer :
das ist besser als
Die Abschreibung ist auf die aktuellen ECMAScript- Gestaltungsprinzipien zurückzuführen .
quelle
Nur eine Erweiterung. Der Wert von "this" ändert sich während der Rekursion. Im folgenden (modifizierten) Beispiel erhält Fakultät das Objekt {foo: true}.
Beim ersten Aufruf von Fakultät wird das Objekt abgerufen, dies gilt jedoch nicht für rekursive Aufrufe.
quelle
this
beibehalten werden muss, schreiben Sie, wasfactorial.call(this, n-1)
ich beim Schreiben von rekursivem Code tatsächlich festgestellt habe, dass es normalerweise keinenthis
gibt oderthis
auf einen Knoten in einem Baum verweist, und tatsächlich ist es gut, dass er sich ändert.