web-dev-qa-db-ja.com

JavaScriptの効率:「for」と「forEach」

For()ループと.forEachを使用したJavascriptの2017年の現在の標準は何ですか。

私は現在、UdemyのColt Steeles "Web Dev Bootcamp"で作業を進めており、彼の教えではforEachよりもforを好んでいます。ただし、演​​習中にコースワークの一部としてさまざまなものを検索しましたが、forではなくforEach- loopを使用することをお勧めします。ほとんどの人は、forループがより効率的であると述べているようです。

これは、コースが作成されてから(2015年頃)変更されたものですか、それともそれぞれの長所と短所です。

どんなアドバイスも大歓迎です。

66
tonyrobbins

for

forループははるかに効率的です。これは、条件がtrueである間に反復するように特別に設計されたループ構造であり、同時にステッピングメカニズムを提供します(通常は反復子を増やすため)。例:

for (var i=0, n=arr.length; i < n; ++i ) {
   ...
}

これは、for-loopsが常により効率的であることを示唆するものではなく、JSエンジンとブラウザがそれらを最適化したというだけです。長年にわたり、どのループ構造がより効率的であるか(妥協、縮小、逆戻りなど)に関して妥協がありました-異なるブラウザーとJSエンジンは、同じ結果を生成するための異なる方法論を提供する独自の実装を持っています。ブラウザーがパフォーマンスの要求を満たすためにさらに最適化されると、理論的には[].forEachが、forに匹敵するか、より高速になるように実装できます。

利点:

  • 効率的
  • 早期ループ終了(breakおよびcontinueの栄誉)
  • 条件制御(i<nは何でもかまいませんし、配列のサイズにバインドされていません)
  • 変数スコープ(var iは、ループの終了後にiを使用可能のままにします)

forEach

.forEachは、主に配列(MapSetオブジェクトなどの他の列挙可能オブジェクト)を反復処理するメソッドです。これらはnewerであり、主観的に読みやすいコードを提供します。例:

[].forEach((val, index)=>{
   ...
});

利点:

  • 変数の設定は必要ありません(配列の各要素を繰り返します)
  • 関数/矢印関数は、変数をブロックにスコープします
    上記の例では、valは新しく作成された関数のパラメーターになります。したがって、ループの前にvalと呼ばれる変数は、終了後も値を保持します。
  • コードが何をしているのかを識別しやすくなる可能性があるため、主観的に保守性が向上します。列挙可能なものを反復処理します。一方、forループは、任意の数のループスキームに使用できます。

性能

パフォーマンスは扱いにくいトピックであり、通常、予測やアプローチに関してはある程度の経験が必要です。最適化がどの程度必要かを前もって(開発中に)判断するために、プログラマーは、問題事例の過去の経験と、解決策の可能性について十分に理解している必要があります。

JQueryの使用は、場合によっては遅すぎるかもしれません(経験豊富な開発者はそれを知っているかもしれません)が、他の場合は問題ではないかもしれません。その場合、ライブラリのブラウザ間のコンプライアンスと他の機能の実行の容易さ(例、AJAX、イベント処理)は、開発(およびメンテナンス)時間を節約する価値があります。

別の例として、パフォーマンスと最適化がすべてである場合、マシンまたはアセンブリ以外のコードはありません。多くの異なる高レベル言語と低レベル言語があり、それぞれにトレードオフがあるため、明らかにそうではありません。これらのトレードオフには、特殊化、開発の容易さと速度、保守の容易さと速度、最適化されたコード、エラーのないコードなどが含まれますが、これらに限定されません。

アプローチ

何かが最適化されたコードを必要とするかどうかをよく理解していない場合は、一般に、最初に保守可能なコードを書くことをお勧めします。そこから、必要なときにさらに注意が必要なものをテストして特定できます。

ただし、特定の明白な最適化は一般的な慣行の一部であり、何も考える必要はありません。たとえば、次のループを考えます。

for (var i=0; i < arr.length; ++i ){}

ループの各反復に対して、JavaScriptは、各サイクルでのキールックアップコスティング操作であるarr.lengthを取得しています。これがそうでない理由はありません:

for (var i=0, n=arr.length; i < n; ++i){}

これは同じことを行いますが、arr.lengthを一度だけ取得し、変数をキャッシュしてコードを最適化します。

131
vol7ron