jeudi 28 octobre 2010

Piège JavaScript no. 6

Maintenant que j'ai décortiqué les 5 pièges JavaScript proposés par Dmitry Baranovskiy, je suis prêt à me pencher sur ceux du quiz avancé. Essayez-le avant de poursuivre plus loin la lecture de ce billet.

Question # 1 du quiz : dans l'exemple suivant, de quel type est "arguments" ?
(function(){
return typeof arguments;
})();
Choix de réponse :
  • object
  • array
  • arguments
  • undefined
Lors du piège JavaScript no. 4, on a vu comment fonctionnait arguments. Comme on sait qu'il existe automatiquement dans le mécanisme d'une fonction, on peut procéder par élimination et rayer "undefined" de la liste. On peut aussi éliminer le type "arguments" parce qu'on a vu que si on imprimait le contenu de la variable, on obtenait une liste :
console.log(arguments); // []
console.log(arguments); // [1,2,3]
Donc un array. En effet, on ne se trompe pas si on dit que arguments est un array. Mais on n'a pas raison non plus.

Réponse : typeof arguments retourne "object".
// observez-le en assignant le résultat à une variable
// ou imprimez-le avec console.log()
var type = (function(){
console.log(typeof arguments);
return typeof arguments;
})();

alert(type);

// ou bien

var list1 = new Array(1,2,3);
var list2 = [1,2,3];

console.log(typeof list1); // object
console.log(typeof list2); // object
Curieux non ? Surtout si on observe la trace de différents types :
console.log( typeof true ); // boolean
console.log( typeof 1 ); // number
console.log( typeof "hello world" ); // string
console.log( typeof [1,2,3] ); // object
console.log( typeof function(){} ); // function
Contrairement à tous les autres types spécifiques, il faut savoir qu'un array JavaScript est toujours du type object.

1 commentaire:

  1. Remarque supplémentaire: arguments n'est pas un array mais un simple object (en plus du fait que le type d'un array soit "object" comme dit dans le billet).
    En effet [].constructor -> function Array(){...}
    tandis que arguments.constructor -> function Object(){...}
    Donc arguments ressemble à un array avec une propriété length, des indices, ... Mais n'en est pas un, on ne peut pas par exemple itérer dessus avec la methode forEach() comme sur un array classique (et c'est bien dommage).
    Ahhhh ECMAScript !!!
    PS: pour utiliser forEach il suffit de dupliquer la méthode à partir d'Array : arguments.forEach = Array.prototype.forEach; (mais il faut le faire à chaque fois et pour chaque méthode qu'on souhaite utiliser...)

    RépondreEffacer