Rufen Sie jede Funktion in der Liste auf

8

Ich habe eine Reihe von Funktionen und suche nach einer übersichtlichen Weise, um jeden in der richtigen Reihenfolge aufzurufen.

%Vor%

das funktioniert:

%Vor%

und so geht das:

%Vor%

Dies löst jedoch einen TypeError aus:

%Vor%

Warum funktioniert das letzte Beispiel nicht?

    
georg 10.04.2013, 10:21
quelle

3 Antworten

4

Dieser vereinfachte Code weist ein ähnliches Problem auf:

%Vor%

In diesem Fall erinnert sich% ce_de% nicht mehr an den Kontext, aus dem er stammt (d. h. Function.call.call ). Um diesen Kontext zu speichern, könntest du diesen unheiligen Konstrukt Trick verwenden:

%Vor%

Es gibt eine neue Funktion zurück, wobei der Kontext von Function.call an sich selbst gebunden ist, wodurch der Kontext gerettet wird. Sie können diesen Ausdruck in einer neuen Variablen speichern:

%Vor%

Nun ist Function.call identisch mit callFn(alert) . Beachten Sie, dass alle zusätzlichen Argumente unverändert weitergegeben werden, sodass alert.call() callFn(alert, window) aufruft. Das Verständnis dieses Verhaltens ist in Situationen wichtig, in denen alert.call(window) als Teil eines Callbacks wie callFn aufgerufen wird, wobei in jeder Iteration drei Argumente übergeben werden.

%Vor%

In Ihrem Fall verwendet keine der Funktionen in Array.forEach die Argumente, die übergeben werden, aber hinter den Kulissen heißen sie so:

%Vor%

So ist fns gleich dem Index des Elements (d. h. this ) und Number(0) ist gleich dem Array von Funktionen. Der aufmerksame Beobachter hat vielleicht bemerkt, dass der Wert des Elements zwischen den Rissen liegt, obwohl es immer noch mit arguments[0] oder alternativ mit arguments[0][this] (veraltet) referenziert werden kann.

    
Ja͢ck 10.04.2013, 10:48
quelle
5
%Vor%

Hier ist die Arbeit Geige .

Verwenden Sie Function.prototype.call und Function.prototype.apply wie oben, um eine Funktion aufzurufen. Mit call und apply können Sie den Ausführungsumfang und arguments an den Funktionsaufruf übergeben. Wenn Sie das nicht benötigen, können Sie einfach Folgendes tun:

%Vor%

Über Ihren Code:

Array.prototype.map ist eine Funktion, die callback und scope as parameters benötigt. In den ersten beiden Beispielen verwenden Sie eine anonyme Funktion als callback , und Sie rufen den Parameter automatisch an, der an Array.prototype.map übergeben wurde. Um zu erweitern, entspricht Ihr Code dem:

%Vor%

Also das obige ist völlig richtig. Nach dem gleichen Prinzip, indem Sie Function.call.call verwenden, rufen Sie die Funktion f übergeben als Parameter durch map auf.

Aber in Ihrem dritten Beispiel erzwingen Sie eine direkte call via Function.call.prototype.call , aber in diesem Fall wird f nicht mehr als Parameter übergeben, was bedeutet, dass Ihre Function.call.call versuchen wird, undefined aufzurufen. , daher bekommst du TypeError . Wenn Sie Function.call.call in map() setzen, übergeben Sie NOT ein callback als Argument.

Der call wird sofort angezeigt. Function.call.call ist genau dasselbe wie Function.call.call() oder Function.call.call(undefined) , was sofort ausgewertet wird, wenn Sie es wie in Ihrem dritten Beispiel verwenden.

    
flavian 10.04.2013 10:23
quelle
3

Das TypeError tritt auf, weil Function.prototype.call intern this aufruft (mit dem gegebenen Kontext und Parametern, aber das ist in der Diskussion nicht wichtig).

Lass uns die Arbeit umschreiben

%Vor%

als Äquivalent

%Vor%

Es ist jetzt offensichtlich, dass invoker mit f als this aufgerufen wird. Wenn es intern this aufruft, wird die Funktion wie erwartet aufgerufen.

Sehen Sie sich das jetzt an:

%Vor%

und die entsprechende Form

%Vor%

Es sollte offensichtlich sein, dass hier, wenn invoker aufgerufen wird this ist undefined ; Daher kann es nicht selbst aufgerufen werden, und dies führt zum TypeError .

    
Jon 10.04.2013 10:41
quelle