La plupart des didacticiels que j'ai lus sur les tableaux en JavaScript (y compris w3schools et devguru ) suggèrent que vous pouvez initialiser un tableau avec une certaine longueur en passant un entier au constructeur Array en utilisant la var test = new Array(4);
syntaxe.
Après avoir utilisé cette syntaxe généreusement dans mes fichiers js, j'ai exécuté l'un des fichiers via jsLint , et cela a paniqué:
Erreur: problème à la ligne 1, caractère 22: «)» attendu et à la place «4».
var test = nouveau tableau (4);
Problème à la ligne 1, caractère 23: attendu ";" et a vu à la place ')'.
var test = nouveau tableau (4);
Problème à la ligne 1, caractère 23: attend un identifiant et voit à la place ')'.
Après avoir lu l'explication de jsLint sur son comportement , il semble que jsLint n'aime pas vraiment la new Array()
syntaxe, et préfère plutôt []
lors de la déclaration des tableaux.
J'ai donc quelques questions:
D'abord pourquoi? Suis-je en train de courir un risque en utilisant la new Array()
syntaxe à la place? Existe-t-il des incompatibilités de navigateur dont je devrais être conscient?
Et deuxièmement, si je passe à la syntaxe entre crochets, existe-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;
la source
new Array()
en général, mais il estaccord avectaille spécification. Je pense que tout se résume à la cohérence du code dans tout le contexte.Réponses:
Pourquoi voulez-vous initialiser la longueur? Théoriquement, cela n'est pas nécessaire. Cela peut même entraîner un comportement déroutant, car tous les tests qui utilisent le
length
pour savoir si un tableau est vide ou non signaleront que le tableau n'est pas vide.Certains tests montrent que la définition de la longueur initiale des grands tableaux peut être plus efficace si le tableau est rempli par la suite, mais le gain de performances (le cas échéant) semble différer d'un navigateur à l'autre.
jsLint n'aime pas
new Array()
parce que le constructeur est ambigu.crée un tableau vide de longueur 4. Mais
crée un tableau contenant la valeur
'4'
.Concernant votre commentaire: Dans JS, vous n'avez pas besoin d'initialiser la longueur du tableau. Il se développe dynamiquement. Vous pouvez simplement stocker la longueur dans une variable, par exemple
la source
for
boucle qui itère sur la longueur du tableau et le remplit. Je suppose qu'il y aurait d'autres façons de le faire en JavaScript, donc la vraie réponse à "Pourquoi est-ce que je veux faire ça?" est "En raison des vieilles habitudes qui se sont formées lors de la programmation dans d'autres langues." :)new Array(10)
ne crée pas un tableau avec 10 éléments non définis. Il crée simplement un tableau vide d'une longueur de 10. Voir cette réponse pour la vérité désagréable: stackoverflow.com/questions/18947892/…Array(5)
vous donne un tableau de longueur 5 mais sans valeur, vous ne pouvez donc pas le parcourir.Array.apply(null, Array(5)).map(function () {})
vous donne un tableau de longueur 5 et non défini comme des valeurs, maintenant il peut être itéré.Array.apply(null, Array(5)).map(function (x, i) { return i; })
vous donne un tableau de longueur 5 et de valeurs 0,1,2,3,4.Array(5).forEach(alert)
ne fait rien,Array.apply(null, Array(5)).forEach(alert)
vous donne 5 alertesES6
nous donneArray.from
maintenant vous pouvez également utiliserArray.from(Array(5)).forEach(alert)
Si vous souhaitez initialiser avec une certaine valeur, celles-ci sont bonnes à savoir ...
Array.from('abcde')
,Array.from('x'.repeat(5))
ou
Array.from({length: 5}, (v, i) => i) // gives [0, 1, 2, 3, 4]
la source
Array
reçoit plusieurs arguments, il itère sur l'arguments
objet et applique explicitement chaque valeur au nouveau tableau. Lorsque vous appelezArray.apply
avec un tableau ou un objet avec une propriété de longueurArray
va utiliser la longueur pour définir explicitement chaque valeur du nouveau tableau. C'est pourquoiArray(5)
donne un tableau de 5 élisions, alors qu'ilArray.apply(null, Array(5))
donne un tableau de 5 non définis. Pour plus d'informations, consultez cette réponse.Array.apply(null, Array(5))
peut également s'écrireArray.apply(null, {length: 5})
. Il n'y a vraiment pas beaucoup de différence, mais ce dernier est clairement clair que l'intention est de créer un tableau delength 5
, et non un tableau contenant5
Avec ES2015,
.fill()
vous pouvez maintenant simplement faire:Ce qui est beaucoup plus concis que
Array.apply(0, new Array(n)).map(i => value)
Il est possible de laisser tomber le
0
dans.fill()
et exécuter sans arguments, qui remplira le tableau avecundefined
. ( Cependant, cela échouera dans Typescript )la source
When Array is called as a function rather than as a constructor, it also creates and initializes a new Array object. Thus the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments
Array(n).fill()
OU
Remarque: vous ne pouvez pas boucler des emplacements vides, c.-à-d.
Array(4).forEach(() => …)
OU
( sûr dactylographié )
OU
Méthode classique utilisant une fonction (fonctionne dans n'importe quel navigateur)
Création de tableaux imbriqués
Lorsque vous créez un tableau 2D avec
fill
intuitivement, vous devez créer de nouvelles instances. Mais ce qui va réellement se passer, c'est que le même tableau sera stocké comme référence.Solution
Un tableau 3x2 ressemblera donc à ceci:
Tableau à N dimensions
Initialiser un échiquier
la source
a[0].push(9);
// [ [6, 9], [6], [6] ]
devrait êtrea[0].push(9);
// [ [6, 9], [6, 9], [6, 9] ]
parce que chaque tableau imbriqué est stocké comme référence, donc la mutation d'un tableau affecte le reste. Vous l'avez peut-êtreLe plus court:
la source
[
sans utiliser un;
car il tentera de déréférencer la ligne ci-dessus. Donc, un moyen sûr d'utiliser cette ligne de manière prévisible dans n'importe quelle partie du code serait:;[...Array(1000)]//.whateverOpsNeeded()
[...Array(5)].map((item, index) => ({ index }))
essayez aussi ceci:[...Array(5)]; console.log('hello');
const a = 'a'
et la ligne suivante[...Array(5)].//irrelevent
. À votre avis, à quoi résoudrait la première ligne? Ce serait ceconst a = 'a'[...Array(5)]
qui se traduirait par:Uncaught SyntaxError: Unexpected token ...
const a = 'a'
sera une erreur Lint dans ce cas. Quoi qu'il en soit, cela n'a vraiment rien à voir avec cette réponse.ES6 présente
Array.from
ce qui vous permet de créer un àArray
partir de n'importe quel objet "semblable à un tableau" ou itérable :Dans ce cas,
{length: 10}
représente la définition minimale d'un objet "de type tableau" : un objet vide avec juste unelength
propriété définie.Array.from
permet à un deuxième argument de mapper sur le tableau résultant.la source
Cela initialisera la propriété length à 4:
la source
var size = 42; var myArray = eval("["+",".repeat(size)+"]");
? (Pas si grave;)Je suis surpris qu'aucune solution fonctionnelle n'ait été suggérée pour vous permettre de définir la longueur sur une seule ligne. Ce qui suit est basé sur UnderscoreJS:
Pour les raisons mentionnées ci-dessus, j'éviterais de le faire à moins que je veuille initialiser le tableau à une valeur spécifique. Il est intéressant de noter qu'il existe d'autres bibliothèques qui implémentent la gamme, notamment Lo-dash et Lazy, qui peuvent avoir des caractéristiques de performances différentes.
la source
S'il vous plaît, les gens n'abandonnent pas encore leurs anciennes habitudes. Il y a une grande différence de vitesse entre allouer une fois la mémoire puis travailler avec les entrées de ce tableau (comme dans l'ancien) et l'allouer plusieurs fois au fur et à mesure qu'un tableau grandit (ce qui est inévitablement ce que le système fait sous le capot avec d'autres méthodes suggérées) .
Rien de tout cela n'a d'importance bien sûr, jusqu'à ce que vous vouliez faire quelque chose de cool avec des tableaux plus grands. Ensuite, c'est le cas.
Étant donné qu'il ne semble toujours pas y avoir d'option dans JS pour définir la capacité initiale d'une baie, j'utilise ce qui suit ...
Il y a des compromis à faire:
standard
baie réserve en permanence autant d'espace que la plus grande baie que vous ayez demandée.Mais si cela correspond à ce que vous faites, il peut y avoir un gain. Le timing informel met
à assez rapide (environ 50 ms pour le 10000 étant donné qu'avec n = 1000000 il a fallu environ 5 secondes), et
à bien plus d'une minute (environ 90 secondes pour le 10000 sur la même console chromée, soit environ 2000 fois plus lentement). Ce ne sera pas seulement l'allocation, mais aussi les 10000 push, pour la boucle, etc.
la source
(c'était probablement mieux comme commentaire, mais c'est devenu trop long)
Donc, après avoir lu ceci, j'étais curieux de savoir si la pré-allocation était en fait plus rapide, car en théorie elle devrait l'être. Cependant, ce blog a donné quelques conseils le déconseillant http://www.html5rocks.com/en/tutorials/speed/v8/ .
Donc, toujours incertain, je l'ai mis à l'épreuve. Et il s'avère que cela semble en fait plus lent.
Ce code donne les résultats suivants après quelques exécutions occasionnelles:
la source
la source
[5: 0]
c'est un tableau clairsemé et probablement pas ce que l'on veut.Voici une autre solution
Le premier argument de
apply()
est une liaison de cet objet, dont nous ne nous soucions pas ici, nous le définissons doncnull
.Array.apply(..)
appelle laArray(..)
fonction et répartit la{ length: 3 }
valeur de l' objet comme arguments.la source
new Array(n)
pour initialiser un tableau comme celui-cinew Array(n).map(function(notUsed,index){...})
, mais avec cette approche, comme @zangw l'a mentionné, vous pouvez le faire. +1 de moi.Le constructeur du tableau a une syntaxe ambiguë , et JSLint fait juste mal à vos sentiments après tout.
En outre, votre exemple de code est cassé, la deuxième
var
instruction soulèvera unSyntaxError
. Vous définissez la propriétélength
du tableautest
, il n'y a donc pas besoin d'un autrevar
.En ce qui concerne vos options,
array.length
c'est la seule "propre". La question est, pourquoi avez-vous besoin de définir la taille en premier lieu? Essayez de refactoriser votre code pour vous débarrasser de cette dépendance.la source
var test
. C'était une copie et un collage bâclés de ma part.En supposant que la longueur du tableau est constante. En Javascript, voici ce que nous faisons:
const intialArray = new Array(specify the value);
la source
Comme expliqué ci-dessus, l'utilisation
new Array(size)
est quelque peu dangereuse. Au lieu de l'utiliser directement, placez-le dans une "fonction de création de tableau". Vous pouvez facilement vous assurer que cette fonction est exempte de bogues et vous évitez le danger d'appelernew Array(size)
directement. Vous pouvez également lui donner une valeur initiale par défaut facultative. CettecreateArray
fonction fait exactement cela:la source
Dans la plupart des réponses, il est recommandé au
fill
tableau car sinon "vous ne pouvez pas le parcourir" , mais ce n'est pas vrai. Vous pouvez parcourir un tableau vide, mais pas avecforEach
. Les boucles while, for of et i fonctionnent parfaitement.Ne marche pas.
Ces travaux:
Vérifiez ce violon avec les exemples ci-dessus.
Les angulaires
*ngFor
fonctionnent également très bien avec un tableau vide:la source
Vous pouvez définir la longueur du tableau à l'aide de
array.length = youValue
Ce serait donc
la source
La raison pour laquelle vous ne devez pas utiliser
new Array
est illustrée par ce code:Un autre code pourrait perturber la variable Array. Je sais que c'est un peu tiré par les cheveux que n'importe qui é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 entraîner des bogues très difficiles à localiser.
Si vous vouliez un tableau de longueur = x, rempli d'indéfini (comme le
new Array(x)
ferait), vous pouvez le faire:la source
alert
etundefined
, car un autre code pourrait les déranger. Le deuxième exemple est moins lisiblenew Array(4)
et ne donne pas le même résultat: jsfiddle.net/73fKd