C'est plus simple que ça. fn.call et fn.apply permettent d'appeler la fonction fn en changeant son contexte d'appel, c'est-à-dire la valeur du mot-clé this, ce sur quoi la fonction s'applique.
Par exemple:
[1,2,3].concat.call([4,5,6], [7,8,9]);
retournera [4, 5, 6, 7, 8, 9]. On prend la fonction concat de l'objet Array [1,2,3], mais on l'applique sur [4,5,6] avec l'argument [7,8,9]. Donc [1,2,3] a juste servi ici à récupérer la fonction depuis son prototype. Ici ça ne sert à rien vu qu'on aurait pu aussi la récupérer depuis [4,5,6], mais si par exemple tu veux appliquer la fonction concat sur un objet qui n'est pas tout à fait un Array, comme une liste d'arguments par exemple:
1 2 3
| function inverseArguments(){ return [].reverse.call(arguments) }
inverseArguments(1,2,3) // retourne [3, 2, 1] |
Tu n'aurais pas pu faire arguments.reverse() car arguments ne possède pas le prototype de Array et donc la fonction reverse. Du coup on vient récupérer cette fonction depuis une Array vide [] et on l'applique sur notre objet arguments.
Entre apply et call, il n'y a qu'une toute petite différence : pour apply le second argument est une Array contenant les arguments à passer à la fonction, tandis que pour call il faut passer les arguments les uns à la suite des autres. apply est donc utile quand tu as une Array à disposition. Par exemple si tu as une Array de nombres et que tu veux récupérer le plus grand nombre dans cette liste:
Math.max.apply(null, [1,7,5,2,9,3]); // retournera 9
Ici le contexte d'appel de Math.max n'est pas important, on a mis null comme on aurait pu mettre Math ou n'importe quoi d'autre.
Notons qu'avec ES6 et le nouvel opérateur spread "...", on a plus vraiment besoin de apply puisqu'on peut transformer facilement une array en liste d'arguments.
Partager