Je naviguais dans le jardin JavaScript lorsque je me suis retrouvé avec le hack Function.call.apply qui sert à créer des "wrappers rapides et non liés". Ça dit:
Une autre astuce consiste à utiliser les deux appels et à appliquer ensemble pour créer des enveloppes rapides et non liées.
function Foo() {} Foo.prototype.method = function(a, b, c) { console.log(this, a, b, c); }; // Create an unbound version of "method" // It takes the parameters: this, arg1, arg2...argN Foo.method = function() { // Result: Foo.prototype.method.call(this, arg1, arg2... argN) Function.call.apply(Foo.prototype.method, arguments); };
Ce que je ne comprends pas, c'est pourquoi il faut utiliser Function.call.applique lorsque Function.apply suffirait. Après tout, les deux sont équivalent sémantiquement.
Non, Function.call.apply
et Function.apply
ne sont pas les mêmes dans ce cas.
Disons que l'appelant d'origine invoque
Foo.method(t, x, y, z)
Avec appel et postuler ensemble, comme dans le code JavaScript Garden. Cela s'exécute
Function.call.apply(Foo.prototype.method, arguments);
Qui est (de manière lâche, l'écriture des arguments
en notation-notation):
Function.call.apply(Foo.prototype.method, [t, x, y, z]);
this==Foo.prototype.method
invoque Function.call
avec this==Foo.prototype.method
:
Foo.prototype.method.call(t, x, y, z)
Foo.prototype.method
appelle Foo.prototype.method
avec this
ensemble à t
et les arguments x
, y
et z
. Doux. Tout comme dans les commentaires. Nous avons réussi à fabriquer un emballage.
Maintenant, supposons que vous avez laissé parler juste Function.apply
au lieu de Function.call.apply
, que vous prétendez être équivalent sémantiquement. Tu aurais
Function.apply(Foo.prototype.method, arguments);
Qui est (peu)
Function.apply(Foo.prototype.method, [t, x, y, z]);
Foo.prototype.method
appelle la fonction Function
(ugh!) Avec this
ensemble pour Foo.prototype.method
et les arguments t
, x
, y
et z
.
Pas le même.
Cela signifie que vous pouvez utiliser les méthodes d'un objet sur un autre.
Un bon exemple est la variable d'argument que toutes les fonctions ont, c'est comme un tableau, mais pas un tableau afin que vous puissiez appeler les méthodes de tableau sur ce, ainsi:
Array.prototype.join.call(arguments, ",");