samedi 16 juillet 2011
En JavaScript, il existe deux notations pour déclarer un array (new Array() et []). Elles peuvent sembler équivalentes mais il y a une différence importante à considérer. Pour comprendre, le mieux est de suivre l'exécution du code dans la démonstration suivante :
var a1 = new Array();Jusqu'à maintenant, peu de surprises si ce n'est que de déclarer un tableau vide de trois éléments à la dernière étape.
console.log(a1.length); // 0
console.log(a1[0]); // undefined
var a2 = new Array(1,2,3);
console.log(a2.length); // 3
console.log(a2[0]); // 1
// optionnellement
var a3 = new Array(3);
console.log(a3.length); // 3
console.log(a3[0]); // undefined
Poursuivons avec l'équivalent en utilisant la deuxième notation [] :
var b1 = [];Ajoutons-y un degré de difficulté.
console.log(b1.length); // 0
console.log(b1[0]); // undefined
var b2 = [1,2,3];
console.log(b2.length); // 3
console.log(b2[0]); // 1
var b3 = [3];Contrairement à la déclaration avec new Array(), la longueur de b3 sera de 1 car c'est la valeur 3 qui fait partie de l'array et non pas la réservation de 3 "espaces libres" comme dans a3.
console.log(b3.length);
// ajoutons une valeurÀ ce stade-ci, quelle est la grandeur de l'array ?
b3[3] = 2;
console.log(b3.length); // 4Mais d'où viennent ces 2 espaces vides ? Comme nous avons placé la valeur 2 au 3ème indice de l'array b3, la taille du tableau est automatiquement élargie à 4.
console.log(b3); // [3, undefined, undefined, 2]
Maintenant, ajoutons à ce même tableau une valeur à une clé. Quelle sera la grandeur du tableau ? Est-ce que la longueur deviendra 5 ?
b3['x'] = 'y';Eh non, la longueur demeure 4 mais une propriété x a été créée pour stocker la valeur de y. Donc on sait qu'on peut aussi stocker des propriétés si la clé est textuelle. Essayons autre chose.
console.log(b3.length); // 4
console.log(b3); // [3, undefined, undefined, 2]
console.log(b3.x); // y
b3['10'] = 1; // associatif car la clé est textuelle et non numérique ?Vous y comprenez quelque chose ? Le secret ici est que JavaScript tentera toujours de convertir la clé en numérique pour stocker la valeur au bon indice. S'il échoue, il utilisera une propriété associative qui pourra ensuite être appelée des deux façons (b3['x'] ou b.x).
console.log(b3.length); // 11
Ce qu'il faut se rappeler, c'est que selon la manière de déclarer l'array, on ne peut pas s'attendre au même comportement pour éviter des mauvaises surprises.
console.log(Array(5).length); // 5Douglas Crockford, auteur du livre JavaScript, the Good Parts (et impliqué dans le développement du JavaScript par l'apport du fameux JSON), recommande l'utilisation de l'array littéral plutôt que sa forme objet. D'ailleurs, si vous regardez le code source de jQuery, vous noterez qu'en aucun temps la notation new Array() n'est utilisée. Ça devrait vous donner un indice sur la méthode préférée des développeurs les plus expérimentés. Dorénavant, j'essaierai de changer mes habitudes, juste pour pouvoir me faire passer pour un expert ;-)
console.log([5].length); // 1
L'utilisation des types primitifs (i.e : [], {}, etc...) a toujours été la façon de faire la plus conseillée, l'instanciation de types par le biais d'un objet n'apporte que des problèmes : une syntaxe plus longue, l'opérateur typeof qui ne renvoie que object, etc...
C'est quelque chose que je me m'efforce de faire comprendre aux débutants : il ne faut pas s'en servir sous prétexte que c'est plus beau, non, c'est juste une chose à oublier à moins de vraiment savoir s'en servir (notamment pour exploiter le prototype de l'objet).
J'ai rarement lu article aussi peu clair sur ce sujet.
Si c'est juste pour dire qu'écrire "a = [5]" n'équivaut pas à "a = new Array(5"), il y avait plus simple pour l'expliquer...
Pour le reste, les exemples ne diffèrent pas dans leur comportement que l'objet soit créé via la fonction Array ou via la notation litérale.
PS : Douglas Crockford n'a pas été impliqué dans le développement de JavaScript. Il n'a fait que "découvrir" le format JSON qui existait déjà et qui était alors déjà utilisé par les developpeurs (il le dit lui même dans une présentation récente).
On dirait que tu as lu l'article en diagonale. Le billet se veut être une démonstration par l'exemple. C'est facile de chialer et de penser faire mieux quand on écrit en gardant l'anonymat.
Quand je parle du développement de JavaScript, je n'ai jamais dit qu'il avait créé le langage. Il l'a fait évoluer en inventant et en popularisant JSON à partir de caractéristiques existantes dans le langage JavaScript (sources: livre Coders at Work et Wikipedia.
Au troll anonyme de Rennes en France, voici ma réponse à ton dernier commentaire que je n'ai pas publié et qui n'aurait pas su mieux résumer ma pensée : Avant de commenter ici.