マップの使用に関する翻訳資料に注意を向け、機能的なJavaScriptを削減します。 この記事は、主に初心者の開発者を対象としています。新しい標準に関するこのすべての話では、今日のJavaScriptで関数型プログラミングを使用できるおかげで、多くのツールを提供してくれたのはECMAScript 5であることを忘れがちです。 たとえば、
Array
JSオブジェクトに基づくネイティブ
map()および
reduce()メソッド。 それでも
map()
および
reduce()
使用しない場合は、今が開始時です。 最新のJSプラットフォームのほとんどは、ECMAScript 5をネイティブでサポートしています。これらのメソッドを使用すると、コードがよりきれいになり、読みやすくなり、保守しやすくなります。
map()
および
reduce()
は、よりエレガントな機能開発パスに着手するのに役立ちます。
パフォーマンスノート
もちろん、状況によって必要とされる場合、コードの可読性と保守性がパフォーマンスを低下させることはありません。 最新のブラウザは、ループなど、よりかさばる従来のデザインを
より効率的に実行します。
次の方法を試してください。まず、読みやすさと保守性の基準に基づいてコードを記述し、次に実際に必要な場合はパフォーマンスを最適化します。 時期尚早な最適化を避けます。
また、
map()
や
reduce()
map()
などのメソッドを使用すると、ブラウザがその使用に最適化されるため、JSエンジンの改善点をさらに活用できることにも注意してください。 パフォーマンスに問題がない場合は、将来を楽観的な見方でコードを書くのが最善です。 そして、コードをすっきりさせるパフォーマンストリックは、必要なときに後で使用できるようにします。
地図を使用する
マッピングは、関数型プログラミングの基本的な手法です。 同じ長さの別の配列を作成するために、配列のすべての要素を操作するために使用されますが、変換されたコンテンツを使用します。
わかりやすくするために、簡単な例を見てみましょう。 単語の配列があり、元の配列内のすべての単語の長さを含む配列に変換する必要があるとします。 はい、これは最も関連性の高いケースではありませんが、このツールがどのように機能するかを理解することは、将来コードを改善するためにそれを適用するのに役立ちます。
おそらく、
for
ループを使用して説明したタスクを完了する方法を既にご存じでしょう。 たとえば、次のように:
var animals = ["cat","dog","fish"]; var lengths = []; var item; var count; var loops = animals.length; for (count = 0; count < loops; count++){ item = animals[count]; lengths.push(item.length); } console.log(lengths);
ここでいくつかの変数が定義されています:
animals
配列にはソースワードが含まれます。lengths
空の配列には、操作の結果が含まれます。item
変数は、各サイクルの実行中に操作する配列の各要素を一時的に保存するために使用されます。for
配列には内部変数count
が含まれ、変数ループを使用して最適化されます。
次に、
animals
配列の各要素を繰り返します。長さを計算し、
lengths
配列に入れます。
注:このタスクは、要素変数と中間の割り当てなしで、 animals[count]
の長さanimals[count]
直接lengths
配列に渡すことで、より簡潔に解決できます。 この単純な例でも、コードは少し短くなりますが、読みにくくなります。 同様に、パフォーマンスをわずかに改善するために、既知の長さのanimals
配列を使用してlengths
配列をnew Array(animals.length)
として初期化し、 push
を使用push
代わりにインデックスで要素を挿入します。 しかし、それはまた、コードを少しわかりにくくします。 一般的に、すべては実際のプロジェクトでコードをどのように使用するかに依存します。技術的には、これが正しいアプローチです。 標準のJSエンジンで動作します。 しかし、
map()
について学ぶとき、古典的な方法はすぐに面倒に見えます。
map()
問題を解決する方法は次のとおりです。
var animals = ["cat","dog","fish"]; var lengths = animals.map(function(animal) { return animal.length; }); console.log(lengths);
ここで、
animals
配列の変数から再び始めます。 しかし、それとは別に、
lengths
のみを宣言し、無名のインライン関数を
animals
配列の各要素にマッピングすることで得られた結果を直接割り当てます。 無名関数は、各動物に対して操作を実行し、長さを返します。 最終的に、各単語の長さを含む
lengths
配列は、元の
animals
と同じ長さになります。
このアプローチでは次のことに注意してください。
- コードははるかに短いです。
- 宣言する変数ははるかに少ないです。 そのため、グローバル名前空間でのノイズが少なくなり、同じコードの別の部分が同じ名前の変数を使用する場合の衝突の可能性が減少します。
- サイクルの最初から最後まで値を変更する必要がある変数は1つではありません。 関数型プログラミングを学習するにつれて、定数と不変変数を使用するエレガントな力にますます感謝するでしょう。 そして、始めるのに遅すぎることはありません。
このアプローチのもう1つの利点は、指定された関数を分離することにより、より柔軟にできることです。 これにより、コードがきれいになります。 匿名のインライン関数は、コードの再利用を困難にし、面倒に見える場合があります。 名前付き
getLength()
関数を
getLength()
て、次のように使用できます。
var animals = ["cat","dog","fish"]; function getLength(word) { return word.length; } console.log(animals.map(getLength));
コードがどれほどきれいになり始めたかをご覧ください。 マッピングの適用を開始するだけで、すぐに新しいレベルの関数型プログラミングに到達できます。
ファンクターとは何ですか?
不思議なことに、配列オブジェクトにマッピングを追加すると、ECMAScript 5はメイン配列タイプを完全なファンクターに変えます。 これにより、関数型プログラミングがさらに手頃になります。
関数型プログラミングの古典的な定義によれば、ファンクターは3つの基準を満たします。
- 値のセットが含まれます。
- 各要素を操作する
map
関数を実装しmap
。 map
関数は、同じサイズのファンクターを返します。
ファンクターについて詳しく知りたい場合は
、 Matthias Peter Johanssonの
ビデオをご覧ください。
使用する
reduce()メソッドはECMAScript 5で初めて登場しました。map
map()
似てい
map()
が、別のファンクターを作成する代わりに、
reduce()
は単一の結果を生成します。 たとえば、
animals
配列内のすべての単語の長さの合計を数値として取得する必要があります。 おそらく次のようにすぐに書きます。
var animals = ["cat","dog","fish"]; var total = 0; var item; for (var count = 0, loops = animals.length; count < loops; count++){ item = animals[count]; total += item.length; } console.log(total);
初期配列を記述した後、変数
total
を作成して金額を計算し、ゼロを割り当てます。 また、変数
item
作成します。この変数には、forループが実行されるときに、
animals
配列の各反復の結果が格納されます。 変数
count
ループカウンターとして使用され、ループは反復を最適化するために使用されます。
for
ループを開始し、
animals
配列内のすべての単語を繰り返し、それぞれの値を
item
変数に割り当て、単語の長さを累積合計に追加します。
繰り返しますが、技術的には、ここですべてが正常です。 配列を処理し、結果を得ました。 ただし、
reduce()
メソッドを使用すると、これがはるかに簡単になります。
var animals = ["cat","dog","fish"]; var total = animals.reduce(function(sum, word) { return sum + word.length; }, 0); console.log(total);
ここでは、新しい変数
total
を定義し、匿名インライン関数と累積合計という2つのパラメーターを使用して、
animals
配列に
reduce
を適用した後に得られた結果の値を割り当てます。
reduce
は配列の各要素を取り、それに関数を適用し、結果をプログレッシブ合計に追加し、次の反復に渡します。 置換された関数は、2つのパラメーターを受け取ります。現在の合計と、配列から処理される現在の単語です。 この関数は、現在の
total
値をこの単語の長さに追加します。
reduce()
2番目の引数を無効にするため、
total
は数値であることに注意してください。
reduce()
メソッドは2番目の引数がなくても機能しますが、結果は予期したものと異なる場合があります。
total
するときにJavaScriptが使用するロジックの種類を自分で決定してみてください。
おそらく、説明したアプローチは複雑すぎるようです。 これは、呼び出された
reduce()
メソッドのインライン関数の統合定義の結果です。 無名インラインの代わりに名前付き関数を定義しましょう:
var animals = ["cat","dog","fish"]; var addLength = function(sum, word) { return sum + word.length; }; var total = animals.reduce(addLength, 0); console.log(total);
少し長くなりますが、これは必ずしも欠点ではありません。 この場合、
reduce()
メソッドがどうなるかがより明確になります。 配列の各要素に適用される関数と、累積合計の初期値の2つのパラメーターを受け取ります。 この場合、新しい関数
addLength
に累積合計の初期値(ゼロ)を渡します。
addLength()
関数は、2つのパラメーター
addLength()
積算合計と文字列値
addLength()
も取ります。
おわりに
map()
と
reduce()
定期的に使用することに慣れているため、コードをよりクリーンで、柔軟性があり、保守しやすくすることができます。 これにより、JavaScriptで他の機能的アプローチを使用する道が開かれます。
map()
および
reduce()
に加えて、他の新しいメソッドがECMAScript 5に登場しました。 一時的なパフォーマンスの低下は、コードの品質の向上と、開発の楽しさをはるかに上回ります。 アプリケーションで
map()
と
reduce()
が必要かどうかを気にする代わりに、機能的なアプローチを使用して、実際のプロジェクトのパフォーマンスへの影響を測定します。