JavaScriptの4つの配列遍歴方法:for VS forEach()VS for/in VS for/of
15328 ワード
JS騒动の操作.原文:For vs forEach()vs for/in vs for/of in JavaScript 翻訳者:Fundbug この文章は意訳を採用して、著作権は元の作者の所有になります.
私たちはJavaScriptの配列やオブジェクトを巡る様々な方法を持っていますが、それらの違いは非常に疑問です.Airbnnコードスタイルはfor/inとfor/ofを使用禁止です.なぜ知っていますか?
この文章は以下の4つの循環文法の違いを詳しく紹介します. 構文
JavaScriptの配列はObjectであり、これは配列に文字列の属性を追加できることを意味します.
他の3つの循環文法は、数字以外の属性を無視します.
配列の空要素
JavaScript配列は空の要素があります.以下のコード文法は正しいです.配列長は3です.
空の要素を追加する方法もあります.
Node v 11.8.0を使用して、下記のコードをテストします.結果は以下の通りです.
Aync/AwaitとGenerators
もう一つのポイントは、
下のコードは大きいサイズから小さいサイズまで0-9を印刷します.
結論
簡単に言えば、 For-each over an array in JavaScript? Why is using“for…in”with array iteration a bad idea? Aray iteration and holes in JavaScript Funebugについて
FunndebugはJavaScript、微信小プログラム、微信小ゲーム、支払宝小プログラム、React Native、Node.js、JavaオンラインでリアルタイムBUG監視を適用します.2016年に双十一が正式にオンラインしてから、Fundebugは累計で10億+エラー事件を処理しました.有料顧客はGoogle、360、金山軟件、庶民網など多くのブランド企業があります.皆さん、無料で試用してください.
著作権声明
転載する時、作者のFunebugと本文の住所を明記してください.blog.fundebug.com/2019/03/11/…
転載先:https://juejin.im/post/5c85bc0ef265da2de970b2cd
私たちはJavaScriptの配列やオブジェクトを巡る様々な方法を持っていますが、それらの違いは非常に疑問です.Airbnnコードスタイルはfor/inとfor/ofを使用禁止です.なぜ知っていますか?
この文章は以下の4つの循環文法の違いを詳しく紹介します.
for (let i = 0; i < arr.length; ++i)
arr.forEach((v, i) => { /* ... */ })
for (let i in arr)
for (const v of arr)
for
およびfor/in
を使用して、実際の配列要素値ではなく、配列の下のスケールにアクセスできます.for (let i = 0; i < arr.length; ++i) {
console.log(arr[i]);
}
for (let i in arr) {
console.log(arr[i]);
}
for/of
を使用すると、配列の要素値に直接アクセスすることができる.for (const v of arr) {
console.log(v);
}
forEach()
を使用すると、配列の下付きおよび要素値に同時にアクセスすることができる.arr.forEach((v, i) => console.log(v));
数値以外の属性JavaScriptの配列はObjectであり、これは配列に文字列の属性を追加できることを意味します.
const arr = ["a", "b", "c"];
typeof arr; // 'object'
arr.test = "bad"; //
arr.test; // 'abc'
arr[1] === arr["1"]; // true, JavaScript Object
4つの循環文法は、for/in
だけが非デジタル属性を無視しない:const arr = ["a", "b", "c"];
arr.test = "bad";
for (let i in arr) {
console.log(arr[i]); // "a, b, c, bad"
}
だからこそ、for/in
を使用して配列を巡回するのはよくない.他の3つの循環文法は、数字以外の属性を無視します.
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);
}
ポイント:for/in
を使用して配列を巡回しないでください.本当にデジタル属性ではないものを遍歴したいなら.ESLintのGard-for-innルールを使用してfor/in
を禁止することができます.配列の空要素
JavaScript配列は空の要素があります.以下のコード文法は正しいです.配列長は3です.
const arr = ["a", , "c"];
arr.length; // 3
さらに不可解なことに、ループステートメント処理['a',, 'c']
は['a', undefined, 'c']
と同じ方式ではない.['a',, 'c']
では、for/in
とforEach
は空の要素をスキップし、for
とfor/of
はスキップしない.// "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);
}
['a', undefined, 'c']
については、4つの循環文法が一致し、プリントされたものはすべて「a,undefined,c」である.空の要素を追加する方法もあります.
// `['a', 'b', 'c',, 'e']`
const arr = ["a", "b", "c"];
arr[5] = "e";
もう一つは、JSONも空の要素をサポートしていません.JSON.parse('{"arr":["a","b","c"]}');
// { arr: [ 'a', 'b', 'c' ] }
JSON.parse('{"arr":["a",null,"c"]}');
// { arr: [ 'a', null, 'c' ] }
JSON.parse('{"arr":["a",,"c"]}');
// SyntaxError: Unexpected token , in JSON at position 12
ポイント:for/in
とforEach
は空の要素をスキップします.配列中の空の要素は「holes」と呼ばれます.この問題を避けたいなら、無効化を考慮してもいいです.parserOptions:
ecmaVersion: 2018
rules:
no-restricted-syntax:
- error
- selector: CallExpression[callee.property.name="forEach"]
message: Do not use `forEach()`, use `for/of` instead
関数のthisforEach
、for
、for/in
は、外部作用領域のfor/of
を保持する.this
では、矢印関数を使用しない限り、そのコールバック関数のthisが変化します.Node v 11.8.0を使用して、下記のコードをテストします.結果は以下の通りです.
"use strict";
const arr = ["a"];
arr.forEach(function() {
console.log(this); // undefined
});
arr.forEach(() => {
console.log(this); // {}
});
ポイント:ESLINEを使用するforEach
規則は、すべてのコールバック関数に矢印関数を使用する必要があります.Aync/AwaitとGenerators
もう一つのポイントは、
no-arrow-callback
はAync/AwaitとGeneratorsとうまく提携できません.forEach()
コールバック関数でawaitは使用できません.async function run() {
const arr = ['a', 'b', 'c'];
arr.forEach(el => {
// SyntaxError
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(el);
});
}
forEach
コールバック関数ではyieldを使用できません.function* run() {
const arr = ['a', 'b', 'c'];
arr.forEach(el => {
// SyntaxError
yield new Promise(resolve => setTimeout(resolve, 1000));
console.log(el);
});
}
forEach
にとっては、この問題はない.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);
}
}
もちろん、for/of
のコールバック関数をasync関数と定義すると、エラーが発生しません.しかし、forEach()
を順番に実行させたいなら、頭が痛いです.下のコードは大きいサイズから小さいサイズまで0-9を印刷します.
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();
ポイント:できるだけforEach
でaysnc/awaitやgeneratorsを使わないでください.結論
簡単に言えば、
forEach
は巡回的に最も信頼できる方法であり、for/of
よりも循環的に簡潔であり、for
及びfor/in
のように多くの奇怪な特例がない.forEach()
の欠点は、インデックス値を取るのが不便であり、チェーンfor/of
.forEach()
を呼び出すことができないということです.forEach()
を使用して配列インデックスを取得し、このように書くことができる.for (const [i, v] of arr.entries()) {
console.log(i, v);
}
参照FunndebugはJavaScript、微信小プログラム、微信小ゲーム、支払宝小プログラム、React Native、Node.js、JavaオンラインでリアルタイムBUG監視を適用します.2016年に双十一が正式にオンラインしてから、Fundebugは累計で10億+エラー事件を処理しました.有料顧客はGoogle、360、金山軟件、庶民網など多くのブランド企業があります.皆さん、無料で試用してください.
著作権声明
転載する時、作者のFunebugと本文の住所を明記してください.blog.fundebug.com/2019/03/11/…
転載先:https://juejin.im/post/5c85bc0ef265da2de970b2cd