J'essayais de rendre mon code plus petit en mettant en cache des fonctions sur des variables. Par exemple:
function test(){ var a = Array.prototype.slice, b = a.call(arguments); // Do something setTimeout(function(){ var c = a.call(arguments); // Do something else }, 200); }
Donc, au lieu d'appeler Array.prototype.slice.call(arguments)
, je peux simplement faire a.call(arguments);
.
J'essayais de le rendre encore plus petit en mettant en cache Array.prototype.slice.call
, mais cela ne fonctionnait pas.
function test(){ var a = Array.prototype.slice.call, b = a(arguments); // Do something setTimeout(function(){ var c = a(arguments); // Do something else }, 200); }
Cela me donne TypeError: object is not a function
. Pourquoi donc?
typeof Array.prototype.slice.call
renvoie la "function"
, comme prévu.
Pourquoi ne puis-je pas enregistrer .call
à une variable (puis l'appeler)?
Function.prototype.call
est une fonction ordinaire qui fonctionne sur la fonction passée comme this
.
Lorsque vous appelez un call
partir d'une variable, this
devient une window
, ce qui n'est pas une fonction.
Vous devez écrire call.call(slice, someArray, arg1, arg2)
Essaye ça:
function test(){ var a = function(args){ return Array.prototype.slice.call(args); }; b = a(arguments); // Do something setTimeout(function(){ var c = a(arguments); // Do something else }, 200); }
La même erreur se produira si vous essayez de faire quelque chose comme:
var log = console.log; log("Hello");
La raison en est que lorsque vous faites cela, vous assignez la fonction x
(dans mon log
exemple) au log
variables. MAIS la fonction contient un appel à this
qui se réfère maintenant à la window
et non à la console
, ce qui jette une erreur selon laquelle this is not an object
Le problème est que l' call
est une méthode (une fonction qui appartient à un objet) qui s'attend à ce que son propriétaire soit une fonction. Lorsque vous écrivez a = Array.prototype.slice.call
, vous copiez la fonction, mais pas le propriétaire.
Le message "objet n'est pas une fonction" ne dit pas que l' a
n'est pas une fonction, c'est dire qu'elle n'est pas une fonction. Vous pouvez techniquement atteindre ce que vous décrivez en écrivant a.call(Array.prototype.slice, arguments)
, mais évidemment ce n'est pas ce que vous voulez!