JS 面接の質問: forEach はループから抜け出すことができますか?

JS 面接の質問: forEach はループから抜け出すことができますか?

この質問をされたとき、私は無知で頭が真っ白になりました。もちろん、正しく答えられませんでした。私はずっと forEach を誤解していました。本来の for ループよりもはるかに単純なので、書きやすさのために作られた糖衣構文だと思ったこともありました。ビジネスでもよく使われますが、このアプローチの問題点について考えたことはありませんでした。

forEach 使用方法

参考: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach?v=example

arr.forEach(関数コールバック(現在の値、インデックス、配列) {
    //イテレータ
}[, thisArg]);
  • currentValue --- 現在処理中の要素
  • index --- 現在処理されている要素のインデックス
  • 配列 --- forEach が適用される配列

forEach での break と return の使用に関するヒントがあります。原文は次のとおりです。

例外を投げる以外に、forEach()ループを停止したり中断したりする方法はありません。そのような動作が必要な場合、forEach()メソッドは間違ったツールです。代わりに単純なループを使用してください。配列要素を述語としてテストし、ブール値の戻り値が必要な場合は、every()または
代わりに some() を使用してください。使用可能な場合は、新しいメソッド find() または findIndex() を使用して、述語が true の場合の早期終了を行うこともできます。

つまり、forEach で break と return を使用するのは間違いです。break または return を使用する場合は、 every または some 関数を使用してください。

それでタイトルに戻りますが、まず第一に、forEach はループから抜け出す手段を使用できません。なぜでしょうか? forEach は関数を受け取りますが、この関数には通常 2 つのパラメータがあり、1 つ目はループの現在の要素、2 つ目は要素に対応する添え字です。これを手動で実装してみましょう。

Array.prototype.myForEach = 関数 (fn) {
    (i = 0 とします; i < this.length; i++) {
        fn(this[i], i, this);
    }
}

forEach が本当にこのように実装されているかどうかはわかりませんが、上記の単純な疑似コードは forEach の特性を満たしており、実際の for ループ本体を操作する方法がないため、ループから抜け出すことができないことも明らかです。

その後、ドキュメントを調べたところ、forEach の公式定義は私が考えていたような構文上の糖衣ではないことがわかりました。その標準的な記述は、forEach は配列要素ごとに指定した関数を 1 回実行するというものです。この時点で私の考えは徐々に明確になり、公式ドキュメントにも次のような一節があります。

例外をスローする以外に、ループを停止したり、ループから抜け出す方法はありません。この動作が必要な場合、forEach() メソッドは適切なツールではありません。

例外をスローして foreach ループから抜け出す

arr = [0, 1, "stop", 3, 4]とします。
試す {
    arr.forEach(要素 => {
        if (要素 === "stop") {
            新しいエラーをスローします("forEachBreak");
        }
        console.log(element); // 0 1 を出力し、その後は何も出力しません });
} キャッチ (e) {
    console.log(e.message); // 各ブレークごとに
};

もちろん、try-catch ラッパーを使用する場合、ループ本体が大きすぎるとパフォーマンスが低下しますが、これは避けられません。したがって、例外をスローすることは、forEach の問題を解決するための万能薬ではありません。最初に書いた疑似コードに戻りましょう。これを最適化し、渡された関数の判断を実際の for ループに追加します。

Array.prototype.forEach = 関数 (fn) {
    (i = 0 とします; i < this.length; i++) {
        ret = fn(this[i], i, this); とします。
        if (typeof ret !== "undefined" && (ret == null || ret == false)) break;
    }
}

このように、戻り値に応じて自然にループから抜け出すことができます。

arr = [0, 1, "stop", 3, 4]とします。

arr.forEach(要素 => {
    if (要素 === 'stop') は false を返します
    console.log(element); // 0 1 を出力し、その後は何も出力しません });

console.log('return は続行を意味します:');
arr.forEach(要素 => {
    if (要素 === 'stop') 戻り値
    console.log(要素); // 0 1 3 4
});

また、ドキュメントには、forEach には同期関数が必要であることも記載されています。つまり、非同期関数や Promise をコールバックとして使用すると予期しない結果が発生する可能性があるため、forEach は注意して使用するか、まったく使用しないでください。もちろん、これはプロジェクト開発ですべてを完了するために常に単純な for ループを使用する必要があるという意味ではありません。配列を走査する場合は for..of.. を使用し、オブジェクトを走査する場合は for..in.. を使用できます。公式には、forEach ドキュメントの下に他のツール関数もいくつかリストされています。

配列.プロトタイプ.検索()
Array.prototype.findIndex()
配列.プロトタイプ.マップ()
配列.プロトタイプ.フィルター()
Array.prototype.every()
配列.プロトタイプ.some()

さまざまなビジネス シナリオに応じて、対応するツール機能を選択して、ビジネス ロジックをより効率的に処理します。forEach については、今後は忘れることにします。

要約する

これで、 forEach がループから抜け出せるかどうかという JS 面接の質問に関するこの記事は終わりです。 JS forEach がループから抜け出すことに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。 今後とも 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • js の Array.forEach でループを終了する方法の例
  • JS forEachはループから抜け出す2つの実装方法
  • js で forEach、for in、for of ループを使用する例のまとめ
  • js配列forEachインスタンスの詳細な使用方法

<<:  Centos に MYSQL8.X をインストールするチュートリアル

>>:  MySQL InnoDB ストレージ エンジンの詳細

推薦する

フレックスレイアウトは左のテキストオーバーフローを実現し、右のテキストの適応を省略します

テキストの長さに応じて、左側のテキストの幅を自動調整できる状況を実現したい。1行が表示できない場合、...

MySQLが内部一時テーブルを使用するタイミングについて簡単に説明します。

組合執行分析を簡単にするために、次のSQLを例として使用します。 テーブル t1 を作成します ( ...

MySQLクエリ速度を最適化する方法

前の章では、高性能な MySQL に不可欠な、最適化されたデータ型の選択方法とインデックスの効率的な...

require loaderの実装原理の深い理解

序文Node は新しいプログラミング言語ではなく、JavaScript のランタイムに過ぎないとよく...

現在のマウススライドの座標を取得するVue+openlayer5メソッド

序文: Vue プロジェクトで現在のマウスの座標を取得するにはどうすればよいでしょうか。ここで共有す...

mySQLキーワードの実行優先度の説明

以下のように表示されます。表から条件フィールドでグループ化仮想テーブルとフィールドを作成し、フィール...

負のマージントップ値は、ラベルテキストと入力の間の垂直中央揃えの問題を解決します。

ラベルテキストと入力の垂直方向の中央揃えを調整するのは簡単ではありません。padding、verti...

JavaScript でモバイル モーダル ボックスの効果を実現

この記事では、モバイルモーダルボックス効果を実現するためのJavaScriptの具体的なコードを参考...

Linux で Ceph 分散ソフトウェアをインストールして使用する方法に関するチュートリアル

目次序文1. 基本環境1. サービス配信2. ネットワーク構成(全ノード) 3. SSHパスワードフ...

Linux で crond ツールを使用してスケジュールされたタスクを作成する方法

序文Crond は Linux のスケジュール実行ツール (Windows のスケジュールされたタス...

ライフゲームの JavaScript 実装

目次コンセプト紹介論理的ルール完全なコード主な実装コンセプト紹介セルオートマトンとは、コンピュータの...

KVM 仮想化のインストール、展開、管理のチュートリアル

目次1.kvmの展開1.1 kvmのインストール1.2 kvm Web管理インターフェースのインスト...

HTMLはWEB標準の開発の中心的な基盤です

HTML 中心のフロントエンド開発は、ほぼ Web 標準の意味です。共通しているのは「分離」という考...

div+css3 を使用して背景グラデーション ボタンを実装するためのサンプル コード

フロントエンド ページの需要が増加し続けるにつれて、一部のシーンではグラデーションの背景要素が必要に...

SSH経由でローカルLinux仮想マシンに接続するプロセスを記録する

実験環境:物理マシン Windows 10 x64物理NIC情報IPv4 アドレス: 192.168...