Quelle est la différence entre l'utilisation call
et l' apply
invocation d'une fonction?
var func = function() {
alert('hello!');
};
func.apply();
contre func.call();
Existe-t-il des différences de performances entre les deux méthodes susmentionnées? Quand est-il préférable d'utiliser call
plus apply
et vice versa?
javascript
performance
function
dynamic
John Duff
la source
la source
a
à appliquer un tableau d'arguments etc
à appeler des colonnes d'arguments.fn(...input)
lorsque input est un tableau. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Réponses:
La différence est que
apply
vous pouvez invoquer la fonction avecarguments
un tableau;call
nécessite que les paramètres soient répertoriés explicitement. Un mnémonique utile est " A pour un rray et C pour c omma."Voir la documentation de MDN sur l' application et l' appel .
Pseudo syntaxe:
theFunction.apply(valueForThis, arrayOfArgs)
theFunction.call(valueForThis, arg1, arg2, ...)
Il y a aussi, à partir d'ES6, la possibilité d'
spread
utiliser le tableau pour lacall
fonction, vous pouvez voir les compatibilités ici .Exemple de code:
la source
[]
est appelé un tableau ,{}
est appelé un objet .Array.prototype.slice.call(arguments)
ou[].slice.call(arguments)
. appliquer a du sens si vous avez les arguments dans un tableau, par exemple dans une fonction qui appelle une autre fonction avec (presque) les mêmes paramètres. Recommandation Utilisez un appel de fonction normalfuncname(arg1)
si cela fait ce dont vous avez besoin, enregistrez l' appel et postulez pour les occasions spéciales où vous en avez vraiment besoin.call
etapply
prend deux paramètres. Le premier argument de laapply' and
fonction call` doit être l'objet propriétaire et le deuxième paramètre sera respectivement des paramètres séparés par des tableaux ou des virgules. Si vous passeznull
ouundefined
comme premier argument, alors en mode non strict, ils sont remplacés par un objet global, c'estwindow
K. Scott Allen a un bon résumé sur la question.
Fondamentalement, ils diffèrent sur la façon dont ils gèrent les arguments de fonction.
Donc:
la source
call
mais obligatoire pourapply
Pour répondre à la partie sur le moment où utiliser chaque fonction, utilisez
apply
si vous ne connaissez pas le nombre d'arguments que vous passerez, ou s'ils sont déjà dans un tableau ou un objet semblable à un tableau (comme l'arguments
objet pour transmettre vos propres arguments. Utilisez-lecall
autrement, car il n'est pas nécessaire d'envelopper les arguments dans un tableau.Quand je ne passe aucun argument (comme votre exemple), je préfère
call
depuis que je suis d' appeler la fonction.apply
impliquerait que vous appliquez la fonction aux arguments (inexistants).Il ne devrait pas y avoir de différences de performances, sauf peut-être si vous utilisez
apply
et encapsulez les arguments dans un tableau (par exemplef.apply(thisObject, [a, b, c])
au lieu def.call(thisObject, a, b, c)
). Je ne l'ai pas testé, il pourrait donc y avoir des différences, mais ce serait très spécifique au navigateur. C'est probablementcall
plus rapide si vous n'avez pas déjà les arguments dans un tableau etapply
plus rapide si vous en avez.la source
Voici un bon mnémonique. A pply utilise A rrays et A lways prend un ou deux arguments. Lorsque vous utilisez C tout ce que vous avez à C ontant le nombre d'arguments.
la source
apply
n'est requis. Je ne sais pas pourquoi on appelleraapply
oucall
sans paramètre. On dirait que quelqu'un essaie de savoir pourquoi ici stackoverflow.com/questions/15903782/…Bien que ce soit un vieux sujet, je voulais juste souligner que .call est légèrement plus rapide que .apply. Je ne peux pas vous dire exactement pourquoi.
Voir jsPerf, http://jsperf.com/test-call-vs-apply/3
[
UPDATE!
]Douglas Crockford mentionne brièvement la différence entre les deux, ce qui peut aider à expliquer la différence de performance ... http://youtu.be/ya4UHuXNygM?t=15m52s
Appliquer prend un tableau d'arguments, tandis que Call prend zéro ou plusieurs paramètres individuels! Ah hah!
.apply(this, [...])
.call(this, param1, param2, param3, param4...)
la source
Suit un extrait de Closure: The Definitive Guide de Michael Bolin . Cela peut sembler un peu long, mais il est saturé de beaucoup de perspicacité. Extrait de "Annexe B. Concepts JavaScript fréquemment mal compris":
À quoi fait
this
référence lorsqu'une fonction est appeléeLors de l'appel d'une fonction du formulaire
foo.bar.baz()
, l'objetfoo.bar
est appelé récepteur. Lorsque la fonction est appelée, c'est le récepteur qui est utilisé comme valeur pourthis
:S'il n'y a pas de récepteur explicite lorsqu'une fonction est appelée, alors l'objet global devient le récepteur. Comme expliqué dans "goog.global" à la page 47, la fenêtre est l'objet global lorsque JavaScript est exécuté dans un navigateur Web. Cela conduit à un comportement surprenant:
Même si
obj.addValues
etf
reportez - vous à la même fonction, ils se comportent différemment lorsqu'il est appelé parce que la valeur du récepteur est différent dans chaque appel. Pour cette raison, lors de l'appel d'une fonction qui fait référencethis
, il est important de s'assurer qu'ellethis
aura la bonne valeur lors de son appel. Pour être clair, s'ilsthis
n'étaient pas référencés dans le corps de la fonction, le comportement def(20)
etobj.addValues(20)
serait le même.Comme les fonctions sont des objets de première classe en JavaScript, elles peuvent avoir leurs propres méthodes. Toutes les fonctions ont des méthodes
call()
etapply()
qui permettent de redéfinir le récepteur (c'est-à-dire l'objet auquel il sethis
réfère) lors de l'appel de la fonction. Les signatures de méthode sont les suivantes:Notez que la seule différence entre
call()
etapply()
est quecall()
reçoit les paramètres de la fonction sous forme d'arguments individuels, alors qu'il lesapply()
reçoit sous la forme d'un tableau unique:Les appels suivants sont équivalents
f
etobj.addValues
font référence à la même fonction:Cependant, puisque
call()
niapply()
n'utilise la valeur de son propre récepteur pour remplacer l'argument récepteur lorsqu'il n'est pas spécifié, les éléments suivants ne fonctionneront pas:La valeur de
this
ne peut jamais êtrenull
ouundefined
lorsqu'une fonction est appelée. Lorsquenull
ouundefined
est fourni en tant que récepteur àcall()
ouapply()
, l'objet global est utilisé à la place comme valeur pour le récepteur. Par conséquent, le code précédent a le même effet secondaire indésirable que l'ajout d'une propriété nomméevalue
à l'objet global.Il peut être utile de considérer une fonction comme n'ayant aucune connaissance de la variable à laquelle elle est affectée. Cela permet de renforcer l'idée que la valeur de ceci sera liée lorsque la fonction est appelée plutôt que lorsqu'elle est définie.
Fin de l'extrait.
la source
additionalValues
n'est pas référencé à l'intérieur duobj.addValues
corpsvar f = obj.addValues;
devientvar f = obj.addValues.bind(obj)
et maintenant f (20) fonctionnerait sans avoir à utiliser appel ou appliquer à chaque fois.Il est parfois utile qu'un objet emprunte la fonction d'un autre objet, ce qui signifie que l'objet emprunteur exécute simplement la fonction prêtée comme si c'était la sienne.
Un petit exemple de code:
Ces méthodes sont très utiles pour donner aux objets des fonctionnalités temporaires.
la source
console.log
consulter: Qu'est-ce que console.log et comment l'utiliser?Un autre exemple avec Call, Apply et Bind. La différence entre appeler et appliquer est évidente, mais Bind fonctionne comme ceci:
}
la source
Je voudrais montrer un exemple, où l'argument 'valueForThis' est utilisé:
** détails: http://es5.github.io/#x15.4.4.7 *
la source
Call () prend des arguments séparés par des virgules, ex:
.call(scope, arg1, arg2, arg3)
et apply () prend un tableau d'arguments, ex:
.apply(scope, [arg1, arg2, arg3])
voici quelques exemples d'utilisation supplémentaires: http://blog.i-evaluation.com/2012/08/15/javascript-call-and-apply/
la source
À partir des documents MDN sur Function.prototype.apply () :
A partir des documents MDN sur Function.prototype.call () :
De Function.apply et Function.call en JavaScript :
Exemple de code:
Voir aussi ce violon .
la source
La différence fondamentale est qu'il
call()
accepte une liste d'arguments , alors qu'ilapply()
accepte un seul tableau d'arguments .la source
Voici un petit article, j'ai écrit à ce sujet:
http://sizeableidea.com/call-versus-apply-javascript/
la source
La différence est que
call()
prend les arguments de fonction séparément etapply()
prend les arguments de fonction dans un tableau.la source
Nous pouvons différencier l'appel et appliquer des méthodes comme ci-dessous
CALL: Une fonction avec argument fournit individuellement. Si vous connaissez les arguments à passer ou qu'il n'y a aucun argument à passer, vous pouvez utiliser call.
APPLY: appeler une fonction avec l'argument fourni sous forme de tableau. Vous pouvez utiliser apply si vous ne savez pas combien d'arguments vont passer à la fonction.
Il y a un avantage à utiliser apply par rapport à l'appel, nous n'avons pas besoin de changer le nombre d'arguments seulement nous pouvons changer un tableau qui est passé.
Il n'y a pas de grande différence de performances. Mais nous pouvons dire que l'appel est un peu plus rapide que comparer à appliquer, car un tableau doit être évalué dans la méthode apply.
la source
La différence entre ces méthodes et la manière dont vous souhaitez transmettre les paramètres.
«A pour tableau et C pour virgule» est un mnémonique pratique.
la source
Appeler et appliquer les deux sont utilisés pour forcer la
this
valeur lorsqu'une fonction est exécutée. La seule différence est quecall
prend lesn+1
arguments où 1 estthis
et'n' arguments
.apply
prend seulement deux arguments, l'un estthis
l'autre est un tableau d'arguments.L'avantage que je vois
apply
pluscall
est que nous pouvons facilement déléguer un appel de fonction à une autre fonction sans trop d'effort;Observons la facilité avec laquelle nous avons délégué
hello
à l'sayHello
utilisationapply
, maiscall
cela est très difficile à réaliser.la source
Même si
call
et àapply
atteindre la même chose, je pense qu'il y a au moins un endroit où vous ne pouvez pas utiliser,call
mais ne pouvez utiliserapply
. C'est à ce moment que vous souhaitez prendre en charge l'héritage et appeler le constructeur.Voici une fonction qui vous permet de créer des classes qui prennent également en charge la création de classes en étendant d'autres classes.
la source
Sommaire:
Les deux
call()
etapply()
sont des méthodes qui se trouvent surFunction.prototype
. Ils sont donc disponibles sur chaque objet fonction via la chaîne de prototypes. Les deuxcall()
etapply()
peuvent exécuter une fonction avec une valeur spécifiée dethis
.La principale différence entre
call()
etapply()
est la façon dont vous devez lui transmettre des arguments. Dans les deuxcall()
,apply()
vous passez comme premier argument l'objet sous lequel vous souhaitez être la valeurthis
. Les autres arguments diffèrent de la manière suivante:call()
vous devez mettre les arguments normalement (à partir du deuxième argument)apply()
vous devez passer dans un tableau d'arguments.Exemple:
Pourquoi aurais-je besoin d'utiliser ces fonctions?
La
this
valeur peut parfois être délicate en javascript. La valeur dethis
déterminé lorsqu'une fonction est exécutée et non lorsqu'une fonction est définie. Si notre fonction dépend d'unethis
liaison droite, nous pouvons utilisercall()
etapply()
appliquer ce comportement. Par exemple:la source
La principale différence est qu'en utilisant call, nous pouvons changer la portée et passer des arguments comme d'habitude, mais apply vous permet de l'appeler en utilisant des arguments comme un tableau (passez-les comme un tableau). Mais en termes de ce qu'ils doivent faire dans votre code, ils sont assez similaires.
Donc, comme vous le voyez, il n'y a pas de grande différence, mais il y a quand même des cas où nous préférons utiliser call () ou apply (). Par exemple, regardez le code ci-dessous, qui recherche le plus petit et le plus grand nombre dans un tableau à partir de MDN, en utilisant la méthode apply:
Donc, la principale différence est juste la façon dont nous passons les arguments:
Appel:
Appliquer:
la source
Permettez-moi d'ajouter un petit détail à cela.
ces deux appels sont presque équivalents:
Il n'y a qu'une différence mineure:
Donc, ces appels se complètent. Là où nous attendons un itérable ,
call
ça marche, là où nous attendons un tableau , çaapply
marche.Et pour les objets qui sont à la fois itérables et de type tableau , comme un vrai tableau, nous pourrions techniquement utiliser n'importe lequel d'entre eux, mais appliquer sera probablement plus rapide car la plupart des moteurs JavaScript l'optimisent en interne mieux.
la source