apeescape2.com
  • メイン
  • リモートの台頭
  • プロセスとツール
  • 仕事の未来
  • 製品の担当者とチーム
バックエンド

関数型プログラミング入門:JavaScriptパラダイム

関数型プログラミングは、状態やデータを変更せずに式や関数を使用してコンピュータープログラムを構築するパラダイムです。

これらの制限を尊重することにより、関数型プログラミングは、理解しやすく、バグに強いコードを書くことを目的としています。これは、コードの追跡を困難にするフロー制御ステートメント(for、while、break、continue、goto)の使用を回避することで実現されます。また、関数型プログラミングでは、バグが発生しにくい純粋で決定論的な関数を作成する必要があります。

この記事では、JavaScriptを使用して関数型プログラミングを行う方法について説明します。また、それを可能にするさまざまなJavaScriptメソッドと機能についても説明します。最後に、関数型プログラミングに関連するさまざまな概念を調査し、それらが非常に強力である理由を確認します。



ただし、関数型プログラミングに入る前に、純粋関数と不純関数の違いを理解する必要があります。

純粋関数と不純関数

純粋関数はいくつかの入力を受け取り、固定出力を提供します。また、それらは外の世界で副作用を引き起こしません。

const add = (a, b) => a + b;

ここで、add純粋関数です。これは、aの固定値に対しておよびbの場合、出力は常に同じになります。

const SECRET = 42; const getId = (a) => SECRET * a;

getId純粋関数ではありません。その理由は、グローバル変数SECRETを使用しているためです。出力を計算するため。 SECRETの場合変更されることになった、getId関数は、同じ入力に対して異なる値を返します。したがって、それは純粋関数ではありません。

let id_count = 0; const getId = () => ++id_count;

これも不純な関数であり、2つの理由から、(1)出力の計算に非ローカル変数を使用し、(2)変数を変更することで、外界に副作用を引き起こします。世界。

個人事業主vsscorpを通過する

getIdは不純なイラストです

このコードをデバッグする必要がある場合、これは面倒な場合があります。

id_countの現在の値は何ですか? id_countを変更している他の関数はどれですか? id_countに依存する他の関数はありますか?

これらの理由により、関数型プログラミングでは純粋関数のみを使用します。

純粋関数のもう1つの利点は、並列化してメモ化できることです。前の2つの関数を見てください。それらを並列化またはメモ化することは不可能です。これは、パフォーマンスの高いコードの作成に役立ちます。

関数型プログラミングの信条

これまでのところ、関数型プログラミングはいくつかのルールに依存していることを学びました。以下のとおりです。

  1. データを変更しないでください
  2. 純粋関数を使用する:固定入力の固定出力、および副作用なし
  3. 式と宣言を使用する

これらの条件を満たすと、コードは機能していると言えます。

JavaScriptでの関数型プログラミング

JavaScriptには、関数型プログラミングを可能にするいくつかの関数がすでにあります。例: String.prototype.slice 、 Array.protoype.filter 、 Array.prototype.join 。

一方、 Array.prototype.forEach 、 Array.prototype.push 不純な機能です。

Array.prototype.forEachと主張することができますは設計上不純な関数ではありませんが、考えてみてください。非ローカルデータを変更するか、副作用を実行する以外に、それを使用して何もすることはできません。したがって、それを不純な関数のカテゴリに入れてもかまいません。

また、JavaScriptには const 宣言。データを変更しないため、関数型プログラミングに最適です。

JavaScriptの純粋関数

JavaScriptによって提供される純粋関数(メソッド)のいくつかを見てみましょう。

フィルタ

名前が示すように、これは配列をフィルタリングします。

array.filter(condition);

ここでの条件は、配列の各項目を取得する関数であり、項目を保持するかどうかを決定し、そのための真のブール値を返す必要があります。

const filterEven = x => x%2 === 0; [1, 2, 3].filter(filterEven); // [2]

filterEvenに注意してください純粋関数です。それが不純だったとしたら、フィルター呼び出し全体が不純になっていたでしょう。

地図

map配列の各項目を関数にマップし、関数呼び出しの戻り値に基づいて新しい配列を作成します。

array.map(mapper)

mapper配列の項目を入力として受け取り、出力を返す関数です。

const double = x => 2 * x; [1, 2, 3].map(double); // [2, 4, 6]

減らす

reduce配列を単一の値に減らします。

array.reduce(reducer);

reducerは、累積値と配列内の次の項目を取得して、新しい値を返す関数です。これは、配列内のすべての値に対して次々にこのように呼び出されます。

const sum = (accumulatedSum, arrayItem) => accumulatedSum + arrayItem [1, 2, 3].reduce(sum); // 6

通話イラストを減らす

コンキャット

concat新しいアイテムを既存の配列に追加して、新しい配列を作成します。 push()とは異なりますpush()という意味でデータを変更するため、データが不純になります。

[1, 2].concat([3, 4]) // [1, 2, 3, 4]

を使用して同じことを行うこともできます 展開する オペレーター。

[1, 2, ...[3, 4]]

Object.assign

Object.assign提供されたオブジェクトから新しいオブジェクトに値をコピーします。関数型プログラミングは不変データを前提としているため、これを使用して既存のオブジェクトに基づいて新しいオブジェクトを作成します。

const obj = {a : 2}; const newObj = Object.assign({}, obj); newObj.a = 3; obj.a; // 2

の出現で ES6 、これは、スプレッド演算子を使用して実行することもできます。

const newObj = {...obj};

独自の純粋関数の作成

純粋関数も作成できます。文字列を複製するために1つやってみましょうn何度か。

const duplicate = (str, n) => n <1 ? '' : str + duplicate(str, n-1);

この関数は文字列を複製しますn時間を計り、新しい文字列を返します。

duplicate('hooray!', 3) // hooray!hooray!hooray!

高階関数

高階関数は、関数を引数として受け取り、関数を返す関数です。多くの場合、これらは関数の機能を追加するために使用されます。

const withLog = (fn) => { return (...args) => { console.log(`calling ${fn.name}`); return fn(...args); }; };

上記の例では、withLogを作成します関数を受け取り、ラップされた関数が実行される前にメッセージをログに記録する関数を返す高階関数。

const add = (a, b) => a + b; const addWithLogging = withLog(add); addWithLogging(3, 4); // calling add // 7

withLog HOFは他の関数でも使用でき、競合や余分なコードの記述なしで機能します。これがHOFの美しさです。

const addWithLogging = withLog(add); const hype = s => s + '!!!'; const hypeWithLogging = withLog(hype); hypeWithLogging('Sale'); // calling hype // Sale!!!

結合関数を定義せずに呼び出すこともできます。

withLog(hype)('Sale'); // calling hype // Sale!!!

カリー化

カリー化とは、複数の引数をとる関数を1つまたは複数のレベルの高階関数に分解することを意味します。

addを見てみましょう関数。

const add = (a, b) => a + b;

カレーをするときは、次のように引数を複数のレベルに分けて書き直します。

const add = a => { return b => { return a + b; }; }; add(3)(4); // 7

カリー化の利点はメモ化です。関数呼び出しで特定の引数をメモ化できるようになったため、重複や再計算を行わずに後で再利用できます。

// assume getOffsetNumer() call is expensive const addOffset = add(getOffsetNumber()); addOffset(4); // 4 + getOffsetNumber() addOffset(6);

これは、どこでも両方の引数を使用するよりも確かに優れています。

// (X) DON'T DO THIS add(4, getOffsetNumber()); add(6, getOffsetNumber()); add(10, getOffsetNumber());

カリー化された関数を再フォーマットして簡潔に見せることもできます。これは、カリー化関数呼び出しの各レベルが1行のreturnステートメントであるためです。したがって、使用することができます 矢印関数 ES6で、次のようにリファクタリングします。

const add = a => b => a + b;

組成

数学では、合成は、結合された出力を作成するために、ある関数の出力を別の関数の入力に渡すこととして定義されます。純粋関数を使用しているため、関数型プログラミングでも同じことが可能です。

例を示すために、いくつかの関数を作成しましょう。

最初の関数は範囲で、開始番号aを取りますと終了番号b aの数値で構成される配列を作成しますbへ。

const range = (a, b) => a > b ? [] : [a, ...range(a+1, b)];

次に、配列を受け取り、その中のすべての数値を乗算する関数multiplyがあります。

const multiply = arr => arr.reduce((p, a) => p * a);

これらの関数を一緒に使用して階乗を計算します。

const factorial = n => multiply(range(1, n)); factorial(5); // 120 factorial(6); // 720

階乗を計算するための上記の関数はf(x) = g(h(x))に似ているため、合成プロパティを示します。

結びの言葉

純粋な関数と不純な関数、関数型プログラミング、それを支援する新しいJavaScript機能、および関数型プログラミングのいくつかの重要な概念について説明しました。

この作品が関数型プログラミングへの興味をそそり、コードで試してみる動機付けになることを願っています。私たちは、それがあなたのソフトウェア開発の旅における学習経験とマイルストーンになることを確信しています。

関数型プログラミングは 上手 - 調査した そして 壮健 コンピュータプログラムを書くことのパラダイム。と ES6の導入 、JavaScriptは、これまでよりもはるかに優れた関数型プログラミング体験を可能にします。

基本を理解する

関数型プログラミングとは何ですか?

関数型プログラミングは、宣言と式を使用してコンピュータープログラムを構築するパラダイムです。

JavaScriptは関数型プログラミング言語ですか、それともオブジェクト指向ですか?

ES6の新しい開発のおかげで、JavaScriptは、さまざまなファーストクラスの機能を提供するため、機能的であると同時にオブジェクト指向プログラミング言語であると言えます。

関数型プログラミングの利点は何ですか?

関数型プログラミングは、コード内のフロー制御を簡素化し、変数や状態の変化という形での予期せぬ事態を回避します。これはすべて、バグを回避し、コードを簡単に理解するのに役立ちます。

他の関数型プログラミング言語とは何ですか?

Lisp、Erlang、Haskell、Closure、Pythonは他の関数型プログラミング言語です。これらにおいて、Haskellは、他のプログラミングパラダイムを許可しないという意味で、純粋に関数型プログラミング言語です。

ES6とは何ですか?

ES6またはECMAScript6は、JavaScriptの新しいバージョンであり、矢印関数、定数、スプレッド演算子などの多くの新機能が含まれています。

賢いトラベルハードウェアで生産性を高める

ライフスタイル

賢いトラベルハードウェアで生産性を高める
シニアテクニカルリクルーター

シニアテクニカルリクルーター

その他

人気の投稿
通年続く予算を立てる方法
通年続く予算を立てる方法
SnapchatのIPO:ARPU、ダミーがすべて
SnapchatのIPO:ARPU、ダミーがすべて
意欲的なGoogleGlass開発者向けのチュートリアル:最初のGlassアプリの構築
意欲的なGoogleGlass開発者向けのチュートリアル:最初のGlassアプリの構築
npmのガイド:Node.jsパッケージマネージャー
npmのガイド:Node.jsパッケージマネージャー
単一責任の原則:優れたコードのレシピ
単一責任の原則:優れたコードのレシピ
 
効果的な初期展開パイプラインを構築する方法
効果的な初期展開パイプラインを構築する方法
著名なeコマースのトレンドとそのデザインへの影響(インフォグラフィック付き)
著名なeコマースのトレンドとそのデザインへの影響(インフォグラフィック付き)
オンデマンド製品開発:デジタルトランスフォーメーションの推進
オンデマンド製品開発:デジタルトランスフォーメーションの推進
Twitterデータマイニング:Pythonを使用したビッグデータ分析のガイド
Twitterデータマイニング:Pythonを使用したビッグデータ分析のガイド
PhalconPHP:高負荷のRESTfulAPIのソリューション
PhalconPHP:高負荷のRESTfulAPIのソリューション
人気の投稿
  • AWSソリューションアーキテクト試験に合格する方法
  • 設計図書の作り方
  • llc vs c corp vs s corp
  • ウェアラブルデバイスとは
  • 次のうち、html5、javascript、およびcssに精通しているのはどれですか?
  • ムードボードとは
カテゴリー
プロセスとツール データサイエンスとデータベース リモートの台頭 設計プロセス 仕事の未来 人とチーム Uiデザイン ヒントとツール 技術 財務プロセス

© 2021 | 全著作権所有

apeescape2.com