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)?
3 réponses
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)
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
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!
Questions connexes
Questions liées
De nouvelles questions
javascript
Pour des questions concernant la programmation dans ECMAScript (JavaScript / JS) et ses divers dialectes / implémentations (hors ActionScript). Veuillez inclure toutes les balises pertinentes dans votre question; par exemple, [node.js], [jquery], [json], etc.