diff options
Diffstat (limited to 'files/de/web/javascript/reference/functions/arguments/callee/index.html')
-rw-r--r-- | files/de/web/javascript/reference/functions/arguments/callee/index.html | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/files/de/web/javascript/reference/functions/arguments/callee/index.html b/files/de/web/javascript/reference/functions/arguments/callee/index.html new file mode 100644 index 0000000000..704813b7a6 --- /dev/null +++ b/files/de/web/javascript/reference/functions/arguments/callee/index.html @@ -0,0 +1,157 @@ +--- +title: arguments.callee +slug: Web/JavaScript/Reference/Functions/arguments/callee +tags: + - Deprecated + - Functions + - JavaScript + - Property + - arguments +translation_of: Web/JavaScript/Reference/Functions/arguments/callee +--- +<div>{{jsSidebar("Functions")}}</div> + +<p>Die <strong><code>arguments.callee</code></strong>-Eigenschaft enthält die Referenz der aktuell ausgeführten Funktion.</p> + +<h2 id="Description" name="Description">Beschreibung</h2> + +<p><code>callee</code> ist eine Eigenschaft des <code>arguments</code>-Objektes. Sie kann eingesetzt werden, um aus dem Körper einer Funktion auf die aktuell ausgeführte Funktion zu referenzieren. Dieses ist sinnvoll, wenn der Name der Funktion unbekannt ist. Auch in einer anonymen Funktion (ohne Namen) funktioniert dieses.</p> + +<div class="warning"><strong>Warnung</strong>: Die Version 5 von ECMAScript (ES5) verbietet die nutzung von <code>arguments.callee() im </code>{{jsxref("Strict_mode", "strict mode")}}. Der Einsatz von <code>arguments.callee() </code>soll vermieden werden, wenn function-Ausdrücke einen Namen haben oder Funktionen deklariert werden, die sich selbst aufrufen müssen.</div> + +<h3 id="Warum_wurde_arguments.callee_vom_ES5_strict_mode_entfernt">Warum wurde <code>arguments.callee</code> vom ES5 strict mode entfernt?</h3> + +<p>(angepasst von <a href="http://stackoverflow.com/a/235760/578288" title="http://stackoverflow.com/a/235760/578288">einer Stack Overflow-Antwort von olliej</a>)</p> + +<p>Frühe Versionen von JavaScript erlauben keine benamten Funktions-Anweisungen. Aus diesem Grund ist es nicht möglich rekursive Funktions-Anweisungen zu schreiben.</p> + +<p>Diese Syntax funktioniert, zum Beispiel:</p> + +<pre class="brush: js">function factorial (n) { + return !(n > 1) ? 1 : factorial(n - 1) * n; +} + +[1, 2, 3, 4, 5].map(factorial);</pre> + +<p>aber:</p> + +<pre class="brush: js">[1, 2, 3, 4, 5].map(function (n) { + return !(n > 1) ? 1 : /* what goes here? */ (n - 1) * n; +});</pre> + +<p>funktioniert nicht. Um dieses problem zu lösen wurde <code>arguments.callee</code> hinzugefügt.</p> + +<pre class="brush: js">[1, 2, 3, 4, 5].map(function (n) { + return !(n > 1) ? 1 : arguments.callee(n - 1) * n; +});</pre> + +<p>Allerdings ist dieses eine schlechte Lösung , weil diese (in Verbindung mit anderen <code>arguments</code>, <code>callee</code>, and <code>caller</code>-Problemen) inlining und Endrekursion unmöglich macht (man kann es benutzen um Tracing zu realisieren, jedoch ist der beste Code immer suboptimal). Ein weiteres Problem liegt darin, dass rekursive Aufrufe ein unterschiedliches <code>this</code> bekommen können (siehe folgendes Beispiel):</p> + +<pre class="brush: js">var global = this; + +var sillyFunction = function(recursed) { + if (!recursed) { return arguments.callee(true); } + if (this !== global) { + alert('This is: ' + this); + } else { + alert('This is the global'); + } +} + +sillyFunction();</pre> + +<p>ECMAScript 3 löste das Problem indem benamte Funktions-Ausdrücke erlaubt wurden:</p> + +<pre class="brush: js">[1, 2, 3, 4, 5].map(function factorial (n) { + return !(n > 1) ? 1 : factorial(n - 1)*n; +});</pre> + +<p>Dieses hat zahlreiche Vorteile:</p> + +<ul> + <li>Die Funktion kann wie jede andere Funktion im Code aufgerufen werden.</li> + <li>Es wird keine Variable im äußeren Gültigkeitsbereich erstellt (<a href="http://kangax.github.io/nfe/#example_1_function_expression_identifier_leaks_into_an_enclosing_scope">Ausnahme für IE 8 und kleiner</a>)</li> + <li>Es gibt eine bessere Performance wenn das arguments-Objekt genutzt wird</li> +</ul> + +<p>Eine andere Funktion die verboten wurde ist <code>arguments.callee.caller</code> oder spezifischer <code>Function.caller</code>. Warum ist das so? Zu jedem Zeitpunkt ist es möglich, den tiefsten Aufrufer von jeder Funktion auf dem Stack herauszufinden und weil das herausfinden des Aufrufer-Stacks hat einen hauptsächlichen Effekt: Es macht das Optimieren unmöglich oder sehr viel schwerer. Zum Beispiel ist es nicht Möglich <code>f</code> zu inlinen, wenn nicht sichergestellt ist, dass eine Funktion <code>f</code> nicht eine unbekannte Funktion aufruft. Das bedeutet, dass jeder Aufruf eine große Anzahl an Sicherheitsabfragen durchführen müsste um inlinen zu können.</p> + +<pre class="brush: js">function f(a, b, c, d, e) { return a ? b * c : d * e; }</pre> + +<p>Wenn der JavaScript-Interpreter nicht garantieren kann, dass alle der unterstützten Argumente Nummern beim Aufruf sind, muss dieser Prüfungen für alle Argumente einfügen bevor der Code geinlinet werden kann oder die Funktion kann nicht geinlinet werden. In dieser Situation sollte ein guter Interpreter die Prüfungen neu anordnen, damit diese Optimal abgefragt werden und nur die Werte, die benutzt werden geprüft werden. Weil dieses in vielen Fällen nicht möglich ist, wird es in diesen unmöglich zu inlinen.</p> + +<h2 id="Beispiele">Beispiele</h2> + +<h3 id="Einsatz_von_arguments.callee_in_einer_anonymen_rekursiven_Funktion">Einsatz von <code>arguments.callee</code> in einer anonymen rekursiven Funktion</h3> + +<p>Eine rekursive Funktion muss sich selber aufrufen können. Normalerweise referenziert eine Funktion sich selbst mit dem Namen. Weil eine anonyme Funktion (welche von einem <a href="/de/docs/Web/JavaScript/Reference/Operators/function" title="JavaScript/Reference/Operators/Special/function">Funktionsausdruck</a> oder dem <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Function" title="JavaScript/Reference/Global_Objects/Function"><code>Function</code> Konstruktor</a> erstellt werden kann) hat keinen Namen. Wenn also keine Variable diese Funktion referenziert, ist der einzige Weg die Funktion über <code>arguments.callee</code> aufzurufen.</p> + +<p>Das folgende Beispiel definiert eine Funktion, welche wiederum eine Fakultätsfunktion Definiert und sie zurückgibt. Dieses Beispiel ist nicht sehr praktisch und es gibt fast keine Fälle, in denen dasselbe Ergebnis nicht mit <a href="/de/docs/Web/JavaScript/Reference/Operators/function">Funktionsausdrücken mit Namen</a> erreicht werden kann.</p> + +<pre class="brush: js">function create() { + return function(n) { + if (n <= 1) + return 1; + return n * arguments.callee(n - 1); + }; +} + +var result = create()(5); // returns 120 (5 * 4 * 3 * 2 * 1)</pre> + +<h3 id="Der_einsatz_von_arguments.callee_mit_keinen_guten_Alternativen">Der einsatz von <code>arguments.callee</code> mit keinen guten Alternativen</h3> + +<p>In einem Fall wie dem Folgenden gibt es jedoch keine Alternativen zu arguments.callee, so dass seine Veraltung ein Fehler sein könnte (siehe {{Bug("725398")}}):</p> + +<pre class="brush: js">function createPerson(sIdentity) { + var oPerson = new Function('alert(arguments.callee.identity);'); + oPerson.identity = sIdentity; + return oPerson; +} + +var john = createPerson('John Smith'); + +john();</pre> + +<h2 id="Spezifikationen">Spezifikationen</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Spezifikation</th> + <th scope="col">Status</th> + <th scope="col">Kommentar</th> + </tr> + <tr> + <td>{{SpecName('ES1')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initiale Definition. Implementiert in JavaScript 1.2</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}</td> + <td>{{Spec2('ES6')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Browserkompatibilität">Browserkompatibilität</h2> + + + +<p>{{Compat("javascript.functions.arguments.callee")}}</p> + +<h2 id="See_also" name="See_also">Siehe auch</h2> + +<ul> + <li>{{jsxref("Function")}}</li> +</ul> |