Was ist der Unterschied zwischen dem Verwenden call
und apply
Aufrufen einer Funktion?
var func = function() {
alert('hello!');
};
func.apply();
vs. func.call();
Gibt es Leistungsunterschiede zwischen den beiden oben genannten Methoden? Wann ist es am besten, call
über apply
und umgekehrt zu verwenden?
javascript
performance
function
dynamic
John Duff
quelle
quelle
a
in gelten für Array von Argumenten undc
in Aufruf für Spalten von Argumenten.fn(...input)
wenn die Eingabe ein Array ist. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Antworten:
Der Unterschied besteht darin, dass
apply
Sie die Funktion mitarguments
als Array aufrufen können .call
erfordert, dass die Parameter explizit aufgelistet werden. Eine nützliche mnemonischen ist " A für eine rray und C für c omma."Informationen zum Anwenden und Aufrufen finden Sie in der MDN-Dokumentation .
Pseudo-Syntax:
theFunction.apply(valueForThis, arrayOfArgs)
theFunction.call(valueForThis, arg1, arg2, ...)
Ab ES6 besteht auch die Möglichkeit,
spread
das Array zur Verwendung mit dercall
Funktion zu verwenden. Die Kompatibilitäten finden Sie hier .Beispielcode:
quelle
[]
als Array und{}
als Objekt bezeichnet .Array.prototype.slice.call(arguments)
oder[].slice.call(arguments)
. apply ist sinnvoll, wenn Sie die Argumente in einem Array haben, beispielsweise in einer Funktion, die eine andere Funktion mit (fast) denselben Parametern aufruft. Empfehlung Verwenden Sie einen normalen Funktionsaufruf,funcname(arg1)
wenn dies das ist, was Sie benötigen, und speichern Sie den Anruf und bewerben Sie sich für besondere Anlässe, wenn Sie sie wirklich benötigen.call
undapply
nimmt zwei Parameter. Das erste Argument derapply' and
Funktion call` muss das Eigentümerobjekt sein, und der zweite Parameter besteht aus Array- bzw. durch Kommas getrennten Parametern. Wenn Sie bestehennull
oderundefined
als erstes Argument, dann werden sie im nicht strengen Modus durch ein globales Objekt ersetzt, dhwindow
K. Scott Allen hat eine nette Zusammenfassung zu diesem Thema.
Grundsätzlich unterscheiden sie sich darin, wie sie mit Funktionsargumenten umgehen.
Damit:
quelle
call
aber eine Anforderung fürapply
Um den Teil zu beantworten, wann die einzelnen Funktionen verwendet werden sollen, verwenden
apply
Sie , wenn Sie die Anzahl der übergebenen Argumente nicht kennen oder wenn sie sich bereits in einem Array oder einem Array-ähnlichen Objekt befinden (wie dasarguments
Objekt zum Weiterleiten Ihrer eigenen Argumente). Verwenden Sie escall
anders, da die Argumente nicht in ein Array eingeschlossen werden müssen.Wenn ich keine Argumente (wie Ihr Beispiel) vorbei, ziehe ich es,
call
da ich Aufruf der Funktion.apply
würde bedeuten, dass Sie die Funktion auf die (nicht vorhandenen) Argumente anwenden .Es sollte keine Leistungsunterschiede geben, außer wenn Sie
apply
die Argumente verwenden und in ein Array einschließen (z . B.f.apply(thisObject, [a, b, c])
anstelle vonf.call(thisObject, a, b, c)
). Ich habe es nicht getestet, daher könnte es Unterschiede geben, aber es wäre sehr browserspezifisch. Es ist wahrscheinlichcall
schneller, wenn Sie die Argumente noch nicht in einem Array haben, undapply
schneller, wenn Sie dies tun.quelle
Hier ist eine gute Mnemonik. Eine Anwendung verwendet A- Rrays und A immer ein oder zwei Argumente. Wenn Sie C alles , was Sie haben C ount die Anzahl der Argumente.
quelle
apply
erforderlich ist. Ich bin mir jedoch nicht sicher, warum man aufruftapply
odercall
ohne Parameter. Es sieht so aus, als würde jemand versuchen herauszufinden, warum hier stackoverflow.com/questions/15903782/…Obwohl dies ein altes Thema ist, wollte ich nur darauf hinweisen, dass .call etwas schneller ist als .apply. Ich kann dir nicht genau sagen warum.
Siehe jsPerf, http://jsperf.com/test-call-vs-apply/3
[
UPDATE!
]Douglas Crockford erwähnt kurz den Unterschied zwischen den beiden, was den Leistungsunterschied erklären kann ... http://youtu.be/ya4UHuXNygM?t=15m52s
Apply verwendet eine Reihe von Argumenten, während Call null oder mehr einzelne Parameter akzeptiert! Ah hah!
.apply(this, [...])
.call(this, param1, param2, param3, param4...)
quelle
Es folgt ein Auszug aus Closure: The Definitive Guide von Michael Bolin . Es mag etwas lang aussehen, aber es ist voller Einsichten. Aus "Anhang B. Häufig missverstandene JavaScript-Konzepte":
Worauf
this
bezieht sich, wenn eine Funktion aufgerufen wird ?Beim Aufrufen einer Funktion des Formulars
foo.bar.baz()
wird das Objektfoo.bar
als Empfänger bezeichnet. Wenn die Funktion aufgerufen wird, wird der Empfänger als Wert für Folgendes verwendetthis
:Wenn es beim Aufruf einer Funktion keinen expliziten Empfänger gibt, wird das globale Objekt zum Empfänger. Wie unter "goog.global" auf Seite 47 erläutert, ist window das globale Objekt, wenn JavaScript in einem Webbrowser ausgeführt wird. Dies führt zu überraschendem Verhalten:
Obwohl
obj.addValues
undf
beziehen sich auf dieselbe Funktion, verhalten sie sich beim Aufruf unterschiedlich, da der Wert des Empfängers bei jedem Anruf unterschiedlich ist. Aus diesem Grund ist es beim Aufrufen einer Funktion, auf diethis
verwiesen wird, wichtig sicherzustellen, dass sie beim Aufrufenthis
den richtigen Wert hat. Um klar zu sein, wennthis
im Funktionskörper nicht darauf verwiesen würde, wäre das Verhalten vonf(20)
undobj.addValues(20)
dasselbe.Da Funktionen in JavaScript erstklassige Objekte sind, können sie ihre eigenen Methoden haben. Alle Funktionen haben die Methoden
call()
undapply()
die es ermöglichen , den Empfänger neu zu definieren (dh das Objekt , dasthis
sich bezieht) , wenn die Funktion aufgerufen wird . Die Methodensignaturen lauten wie folgt:Beachten Sie, dass der einzige Unterschied zwischen
call()
und darinapply()
besteht, dasscall()
die Funktionsparameter als einzelne Argumenteapply()
empfangen werden , während sie als einzelnes Array empfangen werden:Die folgenden Aufrufe sind äquivalent
f
undobj.addValues
beziehen sich auf dieselbe Funktion:Da jedoch weder
call()
nochapply()
verwendet den Wert des eigenen Empfängers Ersatz für den Empfänger Argument , wenn es nicht spezifiziert, die folgende nicht funktionieren:Der Wert von
this
kann niemals seinnull
oderundefined
wenn eine Funktion aufgerufen wird. Wennnull
oderundefined
als Empfänger ancall()
oder geliefertapply()
wird, wird stattdessen das globale Objekt als Wert für den Empfänger verwendet. Daher hat der vorherige Code den gleichen unerwünschten Nebeneffekt beim Hinzufügen einer Eigenschaft mit dem Namenvalue
zum globalen Objekt.Es kann hilfreich sein, sich eine Funktion so vorzustellen, dass sie die Variable, der sie zugewiesen ist, nicht kennt. Dies hilft dabei, die Idee zu bekräftigen, dass der Wert davon gebunden wird, wenn die Funktion aufgerufen wird, anstatt wenn sie definiert wird.
Ende des Extrakts.
quelle
additionalValues
nicht innerhalb desobj.addValues
Körpers verwiesen wirdvar f = obj.addValues;
wirdvar f = obj.addValues.bind(obj)
und jetzt würde f (20) funktionieren, ohne jedes Mal einen Anruf verwenden oder anwenden zu müssen.Manchmal ist es nützlich, wenn ein Objekt die Funktion eines anderen Objekts ausleiht, was bedeutet, dass das ausleihende Objekt die verliehene Funktion einfach so ausführt, als wäre es seine eigene.
Ein kleines Codebeispiel:
Diese Methoden sind sehr nützlich, um Objekten temporäre Funktionen zu geben.
quelle
console.log
checken Sie aus: Was ist console.log und wie verwende ich es?Ein weiteres Beispiel mit Call, Apply und Bind. Der Unterschied zwischen Aufrufen und Übernehmen ist offensichtlich, aber Binden funktioniert folgendermaßen:
}}
quelle
Ich möchte ein Beispiel zeigen, in dem das Argument 'valueForThis' verwendet wird:
** Details: http://es5.github.io/#x15.4.4.7 *
quelle
Call () akzeptiert durch Kommas getrennte Argumente, z.
.call(scope, arg1, arg2, arg3)
und apply () verwendet eine Reihe von Argumenten, z.
.apply(scope, [arg1, arg2, arg3])
Hier einige weitere Anwendungsbeispiele: http://blog.i-evaluation.com/2012/08/15/javascript-call-and-apply/
quelle
Aus den MDN-Dokumenten auf Function.prototype.apply () :
Aus den MDN-Dokumenten auf Function.prototype.call () :
Aus Function.apply und Function.call in JavaScript :
Codebeispiel:
Siehe auch diese Geige .
quelle
Ein grundlegender Unterschied besteht darin, dass
call()
eine Argumentliste akzeptiert wird , währendapply()
ein einzelnes Array von Argumenten akzeptiert wird .quelle
Hier ist ein kleiner Beitrag, den ich dazu geschrieben habe:
http://sizeableidea.com/call-versus-apply-javascript/
quelle
Der Unterschied besteht darin, dass
call()
die Funktionsargumente separat undapply()
die Funktionsargumente in einem Array verwendet werden.quelle
Wir können Aufruf- und Anwendungsmethoden wie folgt unterscheiden
CALL: Eine Funktion mit Argumenten wird einzeln bereitgestellt. Wenn Sie die zu übergebenden Argumente kennen oder kein zu übergebendes Argument vorhanden ist, können Sie call verwenden.
APPLY: Rufen Sie eine Funktion mit Argument als Array auf. Sie können apply verwenden, wenn Sie nicht wissen, wie viele Argumente an die Funktion übergeben werden.
Die Verwendung von apply over call bietet den Vorteil, dass wir die Anzahl der Argumente nicht ändern müssen, sondern nur ein übergebenes Array ändern können.
Es gibt keinen großen Unterschied in der Leistung. Wir können jedoch sagen, dass der Aufruf im Vergleich zum Anwenden etwas schneller ist, da ein Array in der Apply-Methode ausgewertet werden muss.
quelle
Der Unterschied zwischen diesen Methoden besteht darin, wie Sie die Parameter übergeben möchten.
"A für Array und C für Komma" ist eine praktische Mnemonik.
quelle
Call und Apply werden verwendet, um den
this
Wert zu erzwingen , wenn eine Funktion ausgeführt wird. Der einzige Unterschied besteht darin , dasscall
nimmtn+1
Argumente , wobei 1this
und'n' arguments
.apply
akzeptiert nur zwei Argumente, eines istthis
das andere Argumentarray.Der Vorteil , den ich in sehen
apply
übercall
ist , dass wir einfach einen Funktionsaufruf an andere Funktion ohne viel Aufwand delegieren;Beobachten Sie, wie einfach wir
hello
diesayHello
Verwendung delegiert habenapply
, abercall
dies ist sehr schwer zu erreichen.quelle
Obwohl
call
undapply
das Gleiche erreichen, denke ich, dass es mindestens einen Ort gibt, an dem Sie nicht verwenden können,call
sondern nur verwenden könnenapply
. In diesem Fall möchten Sie die Vererbung unterstützen und den Konstruktor aufrufen.Mit dieser Funktion können Sie Klassen erstellen, die auch das Erstellen von Klassen durch Erweitern anderer Klassen unterstützt.
quelle
Zusammenfassung:
Beide
call()
undapply()
sind Methoden, die sich auf befindenFunction.prototype
. Daher sind sie für jedes Funktionsobjekt über die Prototypenkette verfügbar. Beidecall()
undapply()
können eine Funktion mit einem bestimmten Wert von ausführenthis
.Der Hauptunterschied zwischen
call()
undapply()
ist die Art und Weise, wie Sie Argumente eingeben müssen. In beidencall()
undapply()
Sie übergeben als erstes Argument das Objekt, als das Sie den Wert haben möchtenthis
. Die anderen Argumente unterscheiden sich folgendermaßen:call()
Sie die Argumente normal eingeben (ab dem zweiten Argument)apply()
Sie eine Reihe von Argumenten übergeben.Beispiel:
Warum sollte ich diese Funktionen verwenden müssen?
Der
this
Wert kann manchmal in Javascript schwierig sein. Der Wert vonthis
bestimmt, wann eine Funktion ausgeführt wird, nicht, wenn eine Funktion definiert ist. Wenn unsere Funktion von einer richtigenthis
Bindung abhängt, können wir dieses Verhalten verwendencall()
undapply()
durchsetzen. Zum Beispiel:quelle
Der Hauptunterschied besteht darin, dass wir mit call den Gültigkeitsbereich ändern und Argumente wie gewohnt übergeben können. Mit apply können Sie ihn jedoch mit Argumenten als Array aufrufen (als Array übergeben). Aber in Bezug auf das, was sie in Ihrem Code tun sollen, sind sie ziemlich ähnlich.
Wie Sie sehen, gibt es keinen großen Unterschied, aber es gibt Fälle, in denen wir call () oder apply () bevorzugen. Sehen Sie sich beispielsweise den folgenden Code an, mit dem die kleinste und größte Zahl in einem Array aus MDN mithilfe der Apply-Methode ermittelt wird:
Der Hauptunterschied besteht also nur in der Art und Weise, wie wir die Argumente übergeben:
Call:
Anwenden:
quelle
Lassen Sie mich dem ein kleines Detail hinzufügen.
Diese beiden Anrufe sind fast gleichwertig:
Es gibt nur einen kleinen Unterschied:
Diese Aufrufe ergänzen sich also. Wo wir ein iterables erwarten ,
call
funktioniert, wo wir ein Array-ähnliches erwarten ,apply
funktioniert.Und für Objekte, die sowohl iterierbar als auch arrayartig sind , wie ein echtes Array, könnten wir technisch jedes davon verwenden, aber die Anwendung wird wahrscheinlich schneller sein, da die meisten JavaScript-Engines es intern besser optimieren.
quelle