953 votes

Comment initialiser la longueur d'un tableau en JavaScript ?

La plupart des tutoriels que j'ai lus sur les tableaux en JavaScript (notamment w3schools et devguru ) suggèrent que vous pouvez initialiser un tableau avec une certaine longueur en passant un entier au constructeur Array en utilisant l'attribut var test = new Array(4); la syntaxe.

Après avoir utilisé cette syntaxe à profusion dans mes fichiers js, j'ai fait passer l'un des fichiers par jsLint et il a flippé :

Erreur : Problème à la ligne 1, caractère 22 : on attendait ')' et on a vu '4' à la place.
var test = new Array(4) ;
Problème à la ligne 1, caractère 23 : on attendait ';' et on a vu ')'.
var test = new Array(4) ;
Problème à la ligne 1, caractère 23 : on attendait un identifiant et on a vu ')' à la place.

Après avoir lu L'explication de jsLint sur son comportement il semble que jsLint n'aime pas vraiment l'élément new Array() et préfère la syntaxe [] lors de la déclaration des tableaux.

J'ai donc quelques questions :

Tout d'abord, pourquoi ? Est-ce que je cours un risque en utilisant le new Array() Existe-t-il des incompatibilités de navigateur dont je dois être conscient ?

Deuxièmement, si je passe à la syntaxe des crochets, y a-t-il un moyen de déclarer un tableau et de définir sa longueur sur une seule ligne, ou dois-je faire quelque chose comme ceci ?

var test = [];
test.length = 4;

1 votes

js standard conseiller également contre en utilisant new Array() en général, mais il n'y a pas de problème à spécifier la taille. Je pense que tout se résume à la cohérence du code dans l'ensemble du contexte.

1 votes

Pour ceux qui cherchent à pré-allouer des structures de tableau plus rigides, il existe Tableaux typés . Notez que les avantages de la performance peuvent varier

0 votes

Veuillez consulter le benchmark suivant qui propose différentes solutions : measurethat.net/Benchmarks/Show/9721/0/

500voto

Felix Kling Points 247451
  1. Pourquoi voulez-vous initialiser la longueur ? Théoriquement, il n'y a pas besoin de le faire. Cela peut même donner lieu à un comportement confus, car tous les tests qui utilisent l'élément length pour savoir si un tableau est vide ou non rapportera que le tableau n'est pas vide.
    Quelques tests montrent que fixer la longueur initiale des grands tableaux peut est plus efficace si le tableau est rempli après coup, mais le gain de performance (s'il y en a un) semble varier d'un navigateur à l'autre.

  2. jsLint n'aime pas new Array() parce que le constructeur est ambigu.

    new Array(4);

    crée un tableau vide de longueur 4. Mais

    new Array('4');

    crée un tableau contenant la valeur '4' .

En ce qui concerne votre commentaire : En JS, vous n'avez pas besoin d'initialiser la longueur du tableau. Elle croît dynamiquement. Vous pouvez simplement stocker la longueur dans une variable, par exemple

var data = [];
var length = 5; // user defined length

for(var i = 0; i < length; i++) {
    data.push(createSomeObject());
}

23 votes

Le nombre d'objets dans le tableau est défini par l'utilisateur, donc je laissais l'utilisateur choisir un nombre, puis j'initialisais le tableau avec ce nombre d'emplacements. Ensuite, je lance un for boucle qui itère sur la longueur du tableau et le remplit. Je suppose qu'il y aurait d'autres façons de faire cela en JavaScript, donc la vraie réponse à la question "Pourquoi est-ce que je veux faire cela ?" est "À cause de vieilles habitudes qui se sont formées en programmant dans d'autres langages". :)

4 votes

@mlms Il suffit de laisser la boucle for itérer sur le nombre défini par l'utilisateur au lieu de devoir définir la longueur du tableau puis d'itérer dessus. Cela n'a pas plus de sens pour vous ?

0 votes

@Šime, oui, c'est ce que je réalisais en tapant mon commentaire. C'est parfaitement logique, mais c'est le genre de choses que je ne ferais pas en C#, que j'ai appris avant (et utilisé plus) que JavaScript.

30voto

Šime Vidas Points 59994

Ceci initialisera la propriété de la longueur à 4 :

var x = [,,,,];

4 votes

C'est astucieux. Il n'a pas la flexibilité du constructeur, parce que vous ne pouvez pas utiliser une variable pour définir la longueur, mais il répond à ma question telle que je l'ai formulée à l'origine, donc +1.

15 votes

Imaginez que vous fassiez cela pour 300 articles alors que la performance compte vraiment !

0 votes

@facildelembrar Que voulez-vous dire ? Faites ce que pour 300 articles ?

15voto

christang Points 146

Je suis surpris qu'une solution fonctionnelle n'ait pas été proposée, permettant de définir la longueur en une seule ligne. Ce qui suit est basé sur UnderscoreJS :

var test = _.map(_.range(4), function () { return undefined; });
console.log(test.length);

Pour les raisons mentionnées ci-dessus, j'éviterais de faire cela à moins de vouloir initialiser le tableau à une valeur spécifique. Il est intéressant de noter qu'il existe d'autres bibliothèques qui implémentent l'intervalle, notamment Lo-dash et Lazy, qui peuvent avoir des caractéristiques de performance différentes.

7 votes

La magie noire du soulignement n'est vraiment pas nécessaire ici. Les dépendances sont comme le sucre, il semble doux au début, mais avant que vous le sachiez, vous avez du diabète.

8voto

j03m Points 1684

(c'était probablement mieux comme commentaire, mais c'est devenu trop long)

Après avoir lu cet article, je me suis demandé si la pré-affectation était réellement plus rapide, car en théorie, elle devrait l'être. Cependant, ce blog donne quelques conseils à ce sujet. http://www.html5rocks.com/en/tutorials/speed/v8/ .

N'étant toujours pas sûr, je l'ai testé. Et il s'avère qu'il semble en fait être plus lent.

var time = Date.now();
var temp = [];
for(var i=0;i<100000;i++){
    temp[i]=i;
}
console.log(Date.now()-time);

var time = Date.now();
var temp2 = new Array(100000);
for(var i=0;i<100000;i++){
    temp2[i] = i;
}
console.log(Date.now()-time); 

Ce code donne les résultats suivants après quelques essais occasionnels :

$ node main.js 
9
16
$ node main.js 
8
14
$ node main.js 
7
20
$ node main.js 
9
14
$ node main.js 
9
19

3 votes

Intéressant, ça semblait inattendu, donc j'ai fait un test JSPerf . Les résultats de Chrome correspondent à vos tests Node, mais Firefox et IE sont légèrement plus rapides lorsque vous pré-allouez de l'espace pour le tableau.

1 votes

@MichaelMartin-Smucker Attendez... cela signifie-t-il que le V8 n'est pas totalement optimisé et parfait ? !?!? :P

0 votes

@mypal125 : En fait, c'est l'inverse. V8 est tellement sur-optimisé que le chemin de code optimisé est plus rapide que ce qui était auparavant le chemin de code le plus rapide. Et l'autre navigateur n'a pas d'optimisations du tout, de sorte que le chemin de code précédemment plus rapide reste plus rapide. Notez que dans le benchmark, même le résultat "lent" de V8 est plus rapide que les résultats rapides des autres navigateurs.

-5voto

nickf Points 185423

La raison pour laquelle vous ne devriez pas utiliser new Array est démontré par ce code :

var Array = function () {};

var x = new Array(4);

alert(x.length);  // undefined...

Un autre code pourrait jouer avec la variable Array. Je sais que c'est un peu tiré par les cheveux que quelqu'un écrive un tel code, mais quand même...

De plus, comme l'a dit Felix King, l'interface est un peu incohérente et pourrait conduire à des bugs très difficiles à localiser.

Si vous vouliez un tableau avec longueur = x, rempli d'indéfini (comme new Array(x) ferait), vous pourriez faire ceci :

var x = 4;
var myArray = [];
myArray[x - 1] = undefined;

alert(myArray.length); // 4

55 votes

Selon ce raisonnement, vous ne devriez pas utiliser alert et undefined car un autre code pourrait les modifier. Le deuxième exemple est moins lisible que new Array(4) et ne vous donne pas le même résultat : jsfiddle.net/73fKd

30 votes

Cette réponse est bizarre

9 votes

Il n'est pas possible d'éviter que les gens s'amusent avec des objets globaux en JavaScript ; il suffit de ne pas le faire ou d'utiliser des frameworks où les gens le font.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X