JavaScriptのループの違いについての詳細な説明

JavaScriptのループの違いについての詳細な説明

序文

JavaScript でループを使用する場合、列挙可能なプロパティと反復可能なオブジェクトという 2 つの重要な要素を正しく定義する必要があります。

列挙可能なプロパティ

列挙可能なオブジェクトの定義特性の 1 つは、代入演算子を使用してオブジェクトにプロパティを割り当てるときに、内部の列挙可能フラグ (enumerable) を true に設定することです。これがデフォルト値です。

ただし、これを false に設定することでこの動作を変更できます。

経験則としては、列挙可能なプロパティは常に for...in ループ内に出現します。

これを見てみましょう:

定数ユーザー = {}
users.languages ​​= 'JavaScript'
​
Object.getOwnPropertyDescriptor(ユーザー、'言語')
// 出力 -> { 値: 'JavaScript'、書き込み可能: true、列挙可能: true、構成可能: true }
​
// ループ内で使用するプロパティをより細かく制御します Object.defineProperty(users, 'role', { value: 'Admin', writable: true, enumerable: false })
​
for (const 項目 in users) {
  console.log(item) // 言語
}

ご覧のとおり、users 変数に languages プロパティを追加し、Object.getOwnPropertyDescriptor メソッドを使用して、languages プロパティ記述子の列挙可能なプロパティを true として出力しました。

Object.defineProperty を使用して role 属性を追加し、enumerable を false に設定します。role 属性は for...in ループでは出力されません。つまり、for...in ループ内のプロパティは列挙可能なプロパティです。

反復可能なオブジェクト

オブジェクトは、反復動作を定義している場合、反復可能です。この場合、for...of 構造でループされる値によって反復動作が定義されます。反復可能な組み込み型には、Array、String、Set、Map オブジェクトが含まれますが、これらは @iterator メソッドを指定していないため反復可能ではありません。

基本的に、JavaScript では、すべての反復可能なオブジェクトは列挙可能なオブジェクトですが、すべての列挙可能なオブジェクトが反復可能なオブジェクトであるとは限りません。

これを概念化する 1 つの方法は次のとおりです。for...in はデータ内のオブジェクトを検索し、for...of は繰り返しシーケンスを検索します。

配列データ型で使用した場合、これがどのように機能するかを見てみましょう。

const languages ​​= ['JavaScript', 'Python', 'Go']
​
// for...in ループで使用する for (const language in languages) {
  console.log(言語)
}
// 出力
// 0
// 1
// 2
​
// for...of ループで使用する for (const language of languages) {
  console.log(著者)
}
// 出力 -> JavaScript Python Go

この構造を使用する際に留意すべき点は、typeof が呼び出され、出力がオブジェクトである場合は、for...in ループを使用できることです。

言語変数に対するこの操作を見てみましょう。

typeof languages ​​// "object" -> なので、for inで使用できます

最初は驚くかもしれませんが、配列はインデックスによってキーが付けられる特別なタイプのオブジェクトであることに注意することが重要です。 for...in が構造内のオブジェクトを検索することを知っておくと、非常に役立ちます。 for...in ループはオブジェクトを見つけると、各キーをループします。

次のように、言語配列に対する for ..in ループの動作を視覚化できます。

定数言語 = {
  0: 'JavaScript'、
  1: 「パイソン」
  2: 「行け」
}

注: for...in は、オブジェクトまで追跡できる場合 (またはオブジェクト プロトタイプ チェーンから継承する場合)、特定の順序なしでキーを反復処理します。

また、反復子 for.. of 構造を実装すると、各反復で値がループされます。

forEachメソッドとmapメソッド

forEach メソッドと map メソッドは同じ目的を達成するために使用できますが、動作とパフォーマンス特性は異なります。

基本的なレベルでは、関数が呼び出されると、引数としてコールバックを受け取ります。

次のスニペットを検討してください。

定数スコア各 = [2, 4,8, 16, 32]
定数スコアマップ = [2, 4,8, 16, 32]
定数平方 = (数値) => 数値 * 数値

それぞれの操作の違いを詳しく見てみましょう。

forEach は undefined を返しますが、map は新しい配列を返します。

newScores = [] とします
const resultWithEach = scoresEach.forEach(スコア => {
  const newScore = square(スコア)
  新しいスコアをプッシュします
})
​
const resultWithMap = scoresMap.map(square)
​
console.log(resultWithEach) // 未定義
console.log(resultWithMap) // [4, 16, 64, 256, 1024]

Map は純粋な関数ですが、 forEach はいくつかの変更を実行します。

console.log(newScores) // [4, 16, 64, 256, 1024]

私の意見では、 map は関数型プログラミングのパラダイムをサポートしています。 forEach では newScores 変数を変更する必要がありましたが、これとは異なり、目的の結果を得るために常に変更を実行する必要はありません。各実行で同じ入力が提供されると、マップ関数は同じ結果を生成します。一方、forEach の対応する部分は、最後のミューテーションからの前の値から取得されます。

チェーン呼び出し

返される結果は配列なので、Map は呼び出しを連鎖するために使用できます。したがって、他の配列メソッドは結果に対してすぐに呼び出すことができます。つまり、filter、reduce、some などのメソッドを呼び出すことができます。戻り値が未定義であるため、forEach ではこれは不可能です。

パフォーマンス

多くの場合、map メソッドは forEach メソッドよりもパフォーマンスが優れています。

map と forEach を使用して実装された同等のコード ブロックのパフォーマンスを確認します。平均すると、マップ関数の実行速度が少なくとも 50% 速くなります。

結論は

上で説明したすべてのループ構造の中で、最も制御しやすいのは for..of ループです。キーワード return、continue、break と一緒に使用できます。つまり、配列内の各要素に対して何が起こるか、また早期に終了するかスキップするかを指定できるということです。

JavaScript のループの違いについての記事はこれで終わりです。JavaScript のループの違いについてさらに詳しく知りたい方は、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続きご覧ください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JavaScript ループトラバーサルの 24 種類のメソッドをすべてご存知ですか?
  • JavaScript イベント ループのケース スタディ
  • JavaScript における 3 つの for ループ ステートメントの使用の概要 (for、for...in、for...of)
  • jsのイベントループ機構の解析
  • JS の配列トラバーサルについて、一般的なループをいくつ知っていますか?
  • 意外と知らないJSのループ速度テストのいろいろを徹底解説
  • JavaScript で円形カルーセルを実装する
  • JavaScript の例におけるループの使用法の詳細な説明

<<:  Docker で Redis クラスターを素早く構築する方法の例

>>:  MySQL のマスタースレーブレプリケーションと読み取り書き込み分離の原理と使用法の詳細な説明

推薦する

Linux 上での Go 環境の構築のインストールと設定の説明

Linux で Go 環境を構築するのは非常に簡単です。 1. go1.2.1.linux-386....

CSSカスケーディングメカニズムについての簡単な説明

CSS にカスケード メカニズムがあるのはなぜですか? CSS では、同じ要素の特定のプロパティに同...

ウィンドウ環境設定Mysql 5.7.21 windowx64.zip無料インストール版チュートリアル詳細説明

1. 公式サイトのmysqlダウンロードページからmysql-5.7.21-windowx64.zi...

HTML ページ適応幅テーブル

WEB アプリケーションのページでは、テーブルがよく使用されます。列の数が限られているため、各列のコ...

アニメーションとトランジションの違い

CSS3アニメーションとJSアニメーションの違いJSはフレームアニメーションを実装しますCSS3はト...

ES6 クラス継承を使用してゴージャスなボール効果を実現する方法

目次導入実装手順キャンバス環境を作成するライティングボールBallクラスを継承するMoveBallク...

MySQL インデックスの原理と使用例の分析

この記事では、例を使用して MySQL インデックスの原理と使用方法を説明します。ご参考までに、詳細...

入力ボックスのコンテンツプロンプトと非表示機能を実装する JavaScript

入力ボックスが小さい場合、内容を入力した後に、入力内容が拡大されたプロンプト ボックスを表示したいこ...

枠線や境界線のない iframe を使用するための完全ガイド (実践経験のまとめ)

<iframe src=”ページのURL” width=”100″ height=”30″ f...

React Contextの理解と応用についてお話ししましょう

目次序文React Context の初見コンテキストの使い方コンテキストを直接取得できるいくつかの...

JavaScript でフロントエンドのカウントダウン効果を実装する

この記事では、フロントエンドのカウントダウン効果を実現するためのJavaScriptの具体的なコード...

Tomcat 例外の解決方法 (リクエスト ターゲットに無効な文字が見つかりました。有効な文字は RFC 7230 および RFC 3986 で定義されています)

1. シナリオ表示Tomcat ログに次の例外情報が時々報告されます。何が起こっているのでしょうか...

React の 3 つの主要属性における Ref の使用に関する詳細な説明

目次クラスコンポーネント機能コンポーネントインタビューのよくある質問: React における ref...

一般的なブラウザのユーザーエージェントの概要

1. 基礎知識: HTTP ヘッダー ユーザーエージェントユーザー エージェントは、ユーザー エージ...

Vue を使用した Amap アプリケーション開発のベスト プラクティス

目次序文非同期読み込みパッケージコンポーネントコンポーネントの使用インターフェースをカスタマイズする...