J'essayais de rendre mon code plus petit en mettant en cache des fonctions dans 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 rendre cela 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 "function", comme prévu.

Pourquoi ne puis-je pas enregistrer .call dans une variable (puis l'appeler)?

8
Rocket Hazmat 16 déc. 2011 à 20:07

3 réponses

Meilleure réponse

Function.prototype.call est une fonction ordinaire qui opère sur la fonction passée comme this.

Lorsque vous appelez call à partir d'une variable, this devient window, qui n'est pas une fonction.
Vous devez écrire call.call(slice, someArray, arg1, arg2)

7
SLaks 16 déc. 2011 à 16:11

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 affectez la fonction x (dans mon exemple log) à la variable log. MAIS , la fonction contient un appel à this qui fait désormais référence à window et non à console, qui génère alors une erreur qui this is not an object

5
Naftali aka Neal 16 déc. 2011 à 16:09

Le problème est que call est une méthode (une fonction qui appartient à un objet) qui s'attend à ce que son propriétaire (son this) soit une fonction. Lorsque vous écrivez a = Array.prototype.slice.call, vous copiez la fonction, mais pas le propriétaire.

Le message "l'objet n'est pas une fonction" ne dit pas que a n'est pas une fonction, il dit que son this n'est pas une fonction. Techniquement, vous pourriez réaliser ce que vous décrivez en écrivant a.call(Array.prototype.slice, arguments), mais ce n'est évidemment pas ce que vous voulez!

4
ruakh 16 déc. 2011 à 16:12
8536847