「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > JavaScript での関数型プログラミングの探索

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

2024 年 11 月 5 日に公開
ブラウズ:814

Exploring Functional Programming in JavaScript

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

関数プログラミングは、計算を数学関数の評価として扱うプログラミング パラダイムです。これにより、状態の変更や可変データが回避されます。基本的な考え方は、純粋な関数を使用してプログラムを構築し、副作用を回避し、不変のデータ構造を操作することです。

関数型プログラミングの主な特徴は次のとおりです:

  • 純粋関数: 同じ入力が与えられると、常に同じ出力が生成され、副作用のない関数。
  • 不変性: データは一度作成すると変更できません。代わりに、データを変更する必要がある場合は、必要な変更を加えた新しいコピーを作成します。
  • 第一級関数: 関数は第一級市民として扱われます。つまり、関数は引数として渡したり、他の関数から返したり、変数に割り当てたりすることができます。
  • 高階関数: 他の関数を引数として受け取るか、結果として返す関数。
  • 宣言コード: どのようにを行うかではなく、何をするかに重点が置かれており、コードがより読みやすく簡潔になります。

JavaScript の関数型プログラミングの中心概念

JavaScript で FP を定義する最も重要な概念のいくつかを見てみましょう。

1. 純粋関数

純粋関数とは、副作用を引き起こさない関数です。つまり、外部状態を変更しません。これは入力パラメータのみに依存し、同じ入力が与えられると、常に同じ出力を返します。


// Pure function example
function add(a, b) {
  return a   b;
}

add(2, 3); // Always returns 5

純粋関数にはいくつかの利点があります:

  • テスト可能性: 純粋な関数は同じ入力に対して常に同じ出力を返すため、テストが簡単です。
  • 予測可能性: 一貫して動作し、デバッグが容易です。

2. 不変性

不変性とは、変数またはオブジェクトが作成されると変更できないことを意味します。代わりに、何かを変更する必要がある場合は、新しいインスタンスを作成します。


const person = { name: "Alice", age: 25 };

// Attempting to "change" person will return a new object
const updatedPerson = { ...person, age: 26 };

console.log(updatedPerson); // { name: 'Alice', age: 26 }
console.log(person); // { name: 'Alice', age: 25 }

データを不変に保つことで、特に複雑なアプリケーションでの予期せぬ副作用のリスクが軽減されます。

3. ファーストクラス関数

JavaScript では、関数は第一級市民です。これは、関数を変数に代入したり、引数として他の関数に渡したり、関数から返すことができることを意味します。このプロパティは関数型プログラミングの鍵となります。


const greet = function(name) {
  return `Hello, ${name}!`;
};

console.log(greet("Bob")); // "Hello, Bob!"

4. 高階関数

高階関数は、他の関数を引数として受け取るか、他の関数を返す関数です。これらは関数型プログラミングの基礎であり、柔軟性の向上とコードの再利用が可能になります。


// Higher-order function
function map(arr, fn) {
  const result = [];
  for (let i = 0; i  x * x);

console.log(squared); // [1, 4, 9, 16]

JavaScript の Array.prototype.map、filter、reduce は、関数型プログラミングに役立つ高階関数の組み込み例です。

5. 関数構成

関数合成とは、複数の関数を 1 つの関数に結合するプロセスです。これにより、ある関数の出力が次の関数の入力となる操作のパイプラインを作成できます。


const multiplyByTwo = (x) => x * 2;
const addFive = (x) => x   5;

const multiplyAndAdd = (x) => addFive(multiplyByTwo(x));

console.log(multiplyAndAdd(5)); // 15

関数の合成は、再利用可能で保守可能なコードを構築するための強力なテクニックです。

6. カレー

カリー化は、複数の引数を取る関数を、それぞれが 1 つの引数を取る関数のシーケンスに変換する手法です。これは、再利用可能な関数や部分的に適用された関数を作成する場合に特に便利です。


function add(a) {
  return function(b) {
    return a   b;
  };
}

const addFive = add(5);
console.log(addFive(3)); // 8

この手法を使用すると、ロジックを書き直すことなく特殊な関数を作成できます。

7. 再帰

再帰は、関数がそれ自体を呼び出して、同じ問題のより小さなインスタンスを解決するもう 1 つの関数型プログラミング手法です。ループには変更可能な状態 (関数型プログラミングでは回避しようとする) が含まれるため、これは FP のループの代替としてよく使用されます。


function factorial(n) {
  if (n === 0) return 1;
  return n * factorial(n - 1);
}

console.log(factorial(5)); // 120

再帰を使用すると、より小さなサブ問題に分割できるタスク用の、よりクリーンで読みやすいコードを作成できます。

8. 副作用の回避

関数が外部状態を変更する場合 (グローバル変数の変更や DOM との対話など)、副作用が発生します。関数型プログラミングの目標は、副作用を最小限に抑え、関数を予測可能かつ自己完結型に保つことです。

副作用の例:

let count = 0;

function increment() {
  count  = 1;  // Modifies external state
}

increment();
console.log(count);  // 1

関数型プログラミングでは、既存の状態を変更する代わりに新しいデータを返すことで、この種の動作を回避します。

FP 代替案:

function increment(value) {
  return value   1;  // Returns a new value instead of modifying external state
}

let count = 0;
count = increment(count);
console.log(count);  // 1

関数型プログラミングの利点

JavaScript で関数型プログラミングを採用すると、多くの利点が得られます:

  • 可読性の向上: FP の宣言的な性質により、コードが読みやすく、理解しやすくなります。 「どのように」ではなく「何を」説明することに重点を置いています。
  • 再利用性とモジュール性: 純粋な関数と関数の合成により、再利用可能なモジュール化されたコードが促進されます。
  • 予測可能性: 純粋な関数と不変性により、バグの数が減り、コードがより予測可能になります。
  • より簡単なテスト: 外部状態への副作用や依存関係がないため、純粋な関数のテストは簡単です。
  • 同時実行性と並列処理: FP を使用すると、変更可能な状態が共有されないため、同時プロセスと並列プロセスを簡単に実装でき、競合状態やデッドロックを回避しやすくなります。

JavaScript の関数型プログラミング ライブラリ

JavaScript は関数型プログラミングの第一級のサポートを備えていますが、ライブラリを使用すると関数型コードを作成する能力を強化できます。人気のあるライブラリには次のものがあります:

  1. Lodash (FP モジュール): Lodash は一般的なプログラミング タスク用のユーティリティ関数を提供し、その FP モジュールを使用すると、より機能的なスタイルで作業できるようになります。


   const _ = require('lodash/fp');
   const add = (a, b) => a   b;
   const curriedAdd = _.curry(add);
   console.log(curriedAdd(1)(2)); // 3
  1. Ramda: Ramda は、JavaScript の関数型プログラミング用に特別に設計されたライブラリです。不変性と関数の合成を促進します。


   const R = require('ramda');
   const multiply = R.multiply(2);
   const add = R.add(3);
   const multiplyAndAdd = R.pipe(multiply, add);

   console.log(multiplyAndAdd(5)); // 13
  1. Immutable.js: このライブラリは、FP 原則に従うのに役立つ永続的な不変データ構造を提供します。


   const { Map } = require('immutable');

   const person = Map({ name: 'Alice', age: 25 });
   const updatedPerson = person.set('age', 26);

   console.log(updatedPerson.toJS()); // { name: 'Alice', age: 26 }
   console.log(person.toJS()); // { name: 'Alice', age: 25 }

結論

関数型プログラミングは、クリーンで予測可能、保守可能な JavaScript コードを作成するための強力なパラダイムを提供します。純粋な関数、不変性に焦点を当て、副作用を回避することで、開発者はより信頼性の高いソフトウェアを構築できます。すべての問題に関数的アプローチが必要なわけではありませんが、FP 原則を統合すると JavaScript プロジェクトが大幅に強化され、コードの編成、テスト容易性、モジュール性が向上します。

JavaScript での作業を続けるときは、必要に応じて関数プログラミング手法を取り入れてみてください。コードベースが成長し、より複雑になるにつれて、FP の利点が明らかになります。

コーディングを楽しんでください!


リリースステートメント この記事は次の場所に転載されています: https://dev.to/manjushsh/exploring-function-programming-in-javascript-3904?1 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3