Maison > interface Web > js tutoriel > le corps du texte

La différence entre les quatre méthodes de parcours de tableau dans JS ( for , forEach() , for/in, for/of)

青灯夜游
Libérer: 2020-10-28 17:46:22
avant
2496 Les gens l'ont consulté

La différence entre les quatre méthodes de parcours de tableau dans JS ( for , forEach() , for/in, for/of)

Nous disposons de plusieurs façons de parcourir des tableaux ou des objets JavaScript, et les différences entre eux sont très déroutantes. Le Le style de codage Airbnb interdit l'utilisation de for/in et for/of, savez-vous pourquoi ?

Cet article présentera en détail les différences entre les quatre syntaxes de boucle suivantes :

  • for (let i = 0; i < arr.length; ++i)
  • arr.forEach((v, i) => { /* ... */ })
  • for (let i in arr)
  • for (const v of arr)

Syntaxe

En utilisant for et for/in, nous pouvons accéder à l'indice du tableau au lieu de la valeur réelle de l'élément du tableau :

for (let i = 0; i < arr.length; ++i) {
    console.log(arr[i]);
}

for (let i in arr) {
    console.log(arr[i]);
}
Copier après la connexion

En utilisant for/of, vous pouvez accéder directement à la valeur de l'élément du tableau :

for (const v of arr) {
    console.log(v);
}
Copier après la connexion

En utilisant forEach(), vous pouvez accéder simultanément à l'indice et à la valeur de l'élément du tableau time :

arr.forEach((v, i) => console.log(v));
Copier après la connexion

Attributs non numériques

Le tableau de JavaScript est un objet, ce qui signifie que nous pouvons ajouter des attributs de chaîne au tableau :

const arr = ["a", "b", "c"];

typeof arr; // &#39;object&#39;

arr.test = "bad"; // 添加非数字属性

arr.test; // &#39;abc&#39;
arr[1] === arr["1"]; // true, JavaScript数组只是特殊的Object
Copier après la connexion

4 types de syntaxe de boucle, seulement for/in n'ignorera pas les attributs non numériques Propriétés numériques :

const arr = ["a", "b", "c"];
arr.test = "bad";

for (let i in arr) {
    console.log(arr[i]); // 打印"a, b, c, bad"
}
Copier après la connexion

Pour cette raison, itérer sur un tableau en utilisant for/in n'est pas bon.

Les trois autres syntaxes de boucle ignoreront les attributs non numériques :

const arr = ["a", "b", "c"];
arr.test = "abc";

// 打印 "a, b, c"
for (let i = 0; i < arr.length; ++i) {
    console.log(arr[i]);
}

// 打印 "a, b, c"
arr.forEach((el, i) => console.log(i, el));

// 打印 "a, b, c"
for (const el of arr) {
    console.log(el);
}
Copier après la connexion

Points : Évitez d'utiliser for/in pour parcourir un tableau, sauf si vous le souhaitez vraiment. -attributs numériques. Vous pouvez utiliser la règle guard-for-in d'ESLint pour désactiver l'utilisation de for/in.

Éléments vides des tableaux

Les tableaux JavaScript peuvent avoir des éléments vides. La syntaxe du code suivante est correcte et la longueur du tableau est de 3 :

const arr = ["a", , "c"];

arr.length; // 3
Copier après la connexion

Ce qui est encore plus déroutant, c'est que l'instruction de boucle gère [&#39;a&#39;,, &#39;c&#39;] et [&#39;a&#39;, undefined, &#39;c&#39;] différemment.

Pour [&#39;a&#39;,, &#39;c&#39;], for/in et forEach ignoreront les éléments vides, tandis que for et for/of ne le seront pas.

// 打印"a, undefined, c"
for (let i = 0; i < arr.length; ++i) {
    console.log(arr[i]);
}

// 打印"a, c"
arr.forEach(v => console.log(v));

// 打印"a, c"
for (let i in arr) {
    console.log(arr[i]);
}

// 打印"a, undefined, c"
for (const v of arr) {
    console.log(v);
}
Copier après la connexion

Pour [&#39;a&#39;, undefined, &#39;c&#39;], les quatre syntaxes de boucle sont les mêmes, et elles impriment toutes "a, indéfini, c".

Il existe une autre façon d'ajouter des éléments vides :

// 等价于`[&#39;a&#39;, &#39;b&#39;, &#39;c&#39;,, &#39;e&#39;]`
const arr = ["a", "b", "c"];
arr[5] = "e";
Copier après la connexion

Encore une chose, JSON ne prend pas non plus en charge les éléments vides :

JSON.parse(&#39;{"arr":["a","b","c"]}&#39;);
// { arr: [ &#39;a&#39;, &#39;b&#39;, &#39;c&#39; ] }

JSON.parse(&#39;{"arr":["a",null,"c"]}&#39;);
// { arr: [ &#39;a&#39;, null, &#39;c&#39; ] }

JSON.parse(&#39;{"arr":["a",,"c"]}&#39;);
// SyntaxError: Unexpected token , in JSON at position 12
Copier après la connexion

Points : < 🎜 > et for/in ignoreront les éléments vides. Les éléments vides du tableau sont appelés forEach"trous". Si vous souhaitez éviter ce problème, vous pouvez envisager de désactiver cetteforEach

de la fonction

:

parserOptions:
    ecmaVersion: 2018
rules:
    no-restricted-syntax:
        - error
        - selector: CallExpression[callee.property.name="forEach"]
          message: Do not use `forEach()`, use `for/of` instead
Copier après la connexion

for et for/in conservera le for/of. de la portée extérieure. this

Pour

, à moins que des fonctions fléchées ne soient utilisées, le this de sa fonction de rappel changera. forEach

Testez le code ci-dessous en utilisant Node v11.8.0 et les résultats sont les suivants :

"use strict";

const arr = ["a"];

arr.forEach(function() {
    console.log(this); // 打印undefined
});

arr.forEach(() => {
    console.log(this); // 打印{}
});
Copier après la connexion

Points clés : Utilisez les règles no-arrow-callback d'ESLint pour exiger tous les rappels La fonction doit utiliser des fonctions fléchées.

Async/Await et Generators

Encore une chose,

ne « coopère » pas bien avec Async/Await et Generators. forEach()

ne peut pas utiliser wait dans la fonction de rappel

 : forEach

async function run() {
  const arr = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;];
  arr.forEach(el => {
    // SyntaxError
    await new Promise(resolve => setTimeout(resolve, 1000));
    console.log(el);
  });
}
Copier après la connexion

ne peut pas utiliser le rendement dans la fonction de rappel

 : forEach

function run() {
  const arr = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;];
  arr.forEach(el => {
    // SyntaxError
    yield new Promise(resolve => setTimeout(resolve, 1000));
    console.log(el);
  });
}
Copier après la connexion

Pour

, alors il y a pas de problème : for/of

async function asyncFn() {
    const arr = ["a", "b", "c"];
    for (const el of arr) {
        await new Promise(resolve => setTimeout(resolve, 1000));
        console.log(el);
    }
}

function* generatorFn() {
    const arr = ["a", "b", "c"];
    for (const el of arr) {
        yield new Promise(resolve => setTimeout(resolve, 1000));
        console.log(el);
    }
}
Copier après la connexion

Bien sûr, si vous définissez la fonction de rappel de

comme une fonction asynchrone, vous n'obtiendrez pas d'erreur. Cependant, si vous souhaitez que forEach()forEach soit exécuté. dans l'ordre , ce sera plutôt un casse-tête.

Le code suivant imprimera 0-9 de grand à petit :

async function print(n) {
    // 打印0之前等待1秒,打印1之前等待0.9秒
    await new Promise(resolve => setTimeout(() => resolve(), 1000 - n * 100));
    console.log(n);
}

async function test() {
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(print);
}

test();
Copier après la connexion

Points : Essayez de ne pas utiliser aysnc/await et les générateurs dans . forEach

Conclusion

En termes simples,

est le moyen le plus fiable de parcourir un tableau. Il est plus concis que la boucle for/of et n'a pas autant de cas particuliers étranges que <. 🎜> et for . L'inconvénient de for/in est qu'il n'est pas pratique pour nous d'obtenir la valeur de l'indice, et nous ne pouvons pas appeler forEach() dans une telle chaîne. for/of

使用for/of获取数组索引,可以这样写:

for (const [i, v] of arr.entries()) {
    console.log(i, v);
}
Copier après la connexion

参考

本文采用意译,版权归原作者所有

原文:http://thecodebarbarian.com/for-vs-for-each-vs-for-in-vs-for-of-in-javascript.html

相关免费学习推荐:js视频教程

更多编程相关知识,请访问:编程入门!!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:fundebug.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal