React学習を楽にしてくれるJavaScriptでの関数型プログラミングの基礎知識

この記事について

この記事は、「JavaScriptでの関数型プログラミング」について、Reactを学ぶ際に足を引っ張らない程度にまとめました。
普段JavaScriptに触れていながら、Reactへの学習障壁を感じている方などの参考になれば幸いです。

Reactに関して初学者向けのチュートリアル記事をいくつか作っています。
是非学習の参考にして下さい。


【 React Hooks入門】useStateを使って買い物リストを作るチュートリアル

【React+TypeScript】Netflixのクローンを作るチュートリアル

なぜReact学習において、関数型プログラミングの知識が必要なのか?

ReactのライバルにあたるVue.jsはhtml、cssとVue.js特有のテンプレート構文を組み合わせる事で、JavaScript力が低くても書きやすい作りになっています。

それに対して、Reactは原理がシンプルで一貫しており、特有の決まり事は少ないのが特徴です。
原理の背後ではJavaScriptと関数型プログラミングへの理解を前提としていて、公式ドキュメントなどでも、関数型についての解説はわざわざ行われていません。

サーバーサイドのRubyやPHPではオブジェクト指向が用いられている背景もあって、関数型プログラミングへの理解が求められるReactはVue.jsに比べて学習コストが高いと思われています。

しかし、Reactを学ぶ前に「JavaScriptの基礎」と「関数型プログラミングの理解」させあれば、React自体はシンプルでとっつきやすい言語だと僕は考えています。

では、React学習を楽にしてくれるJavaScriptでの関数型プログラミングの基礎知識について解説していきます。

関数型プログラミンングの5つの特徴

①関数でプログラミングを構成する

関数型言語では関数だけでコードを組み立てます。
オブジェクト指向ではクラスを使って、様々な処理を行っていました。

「関数だけで組み立てる!」ときいて、流石に無理だろ!と思った人も多いと思うので、関数型でいう所の関数がどういった意図で使われているのかを説明します。

関数型の「関数」とは

よく数学で使う関数と同じ意味でです。
y = f(x)的な感じ。

必ず引数と戻り値があります。
つまり関数型プログラミングとは「引数→戻り値に変換する関数を組み合わせて構築するプログラミング」となります。

今後この記事で関数という場合には、関数型プログラミングにおける関数の事を指していきます。

②全ての式が値を返す

関数では全てが式として書かれ、値を返します。

命令型と宣言型

プログラミングの処理は「命令型」と「宣言型」に分けられます。
命令型は命令文によって順番に状況を変えて行って、最終的に目的の処理を行うやり方です。
手続き型やオブジェクト指向がこれに含まれます。
上から1つずつ処理を追っていけば良いので、直感的に理解しやすいのが特徴です。

宣言型はどんな値が欲しいかを宣言する式を書く事で、目的の値を手に入れます。
SQLなどが代表的で、「欲しいデータに対してSQLを宣言する」といった使い方をします。

宣言型は従来、複雑な処理は難しく、限定的な場面のみで使用されてきました。
関数型プログラミングは宣言型でありながら、複雑な処理が行える点で、オブジェクト指向の次の開発技術として注目された訳です。

言葉だと分かりづらいと思うので簡単な処理で比べてみましょう。
1から100までの数字から6の倍数を格納した配列を吐き出していきます。

手続き型

{
const array = [];
for(let n=1;n<101;n+=1){ 
  if(n%6===0){
   array.push(n); 
  }
}
console.log(array); }

手続き型では、命令文によって構成されています。
・array配列を作る
・1から100までの中で6の倍数の物を配列に入れていく
・出力する
といった処理を順番に行っています。

関数型

{
const range = (start, end) => [...new Array(end - start).keys()].map((n) => n + start);
console.log(range(1, 101).filter((n) => n % 6 === 0)); 
}

関数型は式によって構成されているから、左辺から右辺に評価していく事で値を得ています。
・rangeを作り、引数を入れる事で1~100の配列を作る。
・rangeから6の倍数だけ抜き出す。
といった処理を順番に行っています。

③関数を値としても使える

関数型は②で述べた様に必ず値を返しますが、それに加えて関数を値として利用することも可能です。
つまり関数を変数に代入したり、他の関数の戻り値や引数などの設定する事ができます。

このような性質を持った関数を第一級関数と呼びます。
JavaScriptの関数もその性質を持っている為、関数型プログラミングを行う事ができます。

高階関数

先ほど述べた「引数に関数を取ったり、戻り値として関数を返したりする関数」のことを高階関数と呼びます。
ちなみにJavaScriptでよく出てくるコールバックは、この際に引数として渡された関数の事です。

例を見ていきましょう。

const data = [2,3,4,5];
const result = data.map(function(value,index,array){
  return value * value;
});
console.log(result);//[4, 9, 16, 25]

foreachに近い使われ方をしていますね。
mapは配列の要素を順番に取り出してコールバック関数に渡し,戻り値として加工した結果を返す高階関数です。

今回はdataの中身を順番にコールバック関数に渡し、valueに代入されている為、2→4、3→9と加工されてresultに返ってきています。

Reactでは高階関数の応用として「高階コンポーネント」という、コンポーネントを引数にとってコンポーネントを戻り値として返す概念が使われています。

④関数から新しい関数を作る

関数型プログラミングでは、既存の関数と引数を組み合わせる事で、新しい関数を作る事ができます。
主に部分適応という方法で新しい関数を作りますが、その前にカーリー化について見ておきましょう。

カーリー化

複数の引数を取る関数を、より少ない引数を取る関数に分割して入れ子にすることをカーリー化と呼びます。

//1.カーリー化なし
{
  const multiply = (n, m) => n * m;
  console.log(multiply(2, 4));// 8
}

//2.カーリー化 
{
  const withMultiple = (n) => { 
    return(m)=>n*m;
  };

  console.log(withMultiple(2)(4));//8 
}

//3.カーリー化(アロー関数使用)
{
  const withMultiple = (n) => (m) => n * m;
  console.log(withMultiple(2)(4)); //8 
}

1.で定義したmultiplyはn,mを引数として、その積を返す関数でした。
2.のwithMultipleはnを引数に取った上で、mを引数に取り、nとmの積を返すという高階関数になります。

要するにカーリー化とは
「複数の引数を取る関数を、引数が元の関数の最初の引数で、戻り値が引数として元の関数の残りの引数を取り、それを使って結果を返す関数である高階関数にする事」 となる訳です。

部分適応

さて、カーリー化を押さえた上で、部分適応について確認していきましょう。
部分適用とは、カリー化された関数の一部の引数を固定して新しい関数を作る事です。

コードで見ていきましょう。

const withMultiple = (n) => (m) => n * m; 
console.log(withMultiple(3)(5)); 
//15

const triple = withMultiple(3);
console.log(triple(5));
 // 15

先ほどのカーリー化で作ったwithMultipleに対して、1つ目の引数に3を渡す事で、新しい関数tripleを作っています。
関数tripleは1つ目の引数に3が固定されている為、常に3の倍数を返す関数として機能します。

高階関数や部分適応を使うことで、一時的な変数が不要になり、その分コードが簡潔になるという恩恵を受けられます。

⑤副作用を起こさない

副作用とは自分以外のコードに影響を及ぼす事を指します。

参照透過性

純粋な関数型プログラミングでは、関数は外側の変数を変更しません。引数が同じなら必ず同じ戻り値を吐き出します。これを参照透過性と呼びます。

参照透過性が如何に大事かは、こちらの「プログラマが知るべき97のこと」という名著でも語られています。
関数型プログラミングを学ぶことの重要性

あとがき

Vue.js→Reactと僕自身が学習を進めていく中で、Vue.jsはweb制作やデザイン側の領域との相性の良さや手軽さを感じ、Reactはプログラミング的な背景と原理への立ち返りを感じました。

フロントエンドはITの中でも特に移り変わりが激しく、新しい技術がどんどん出てくる分野ですが、背景にある原理への理解を深める事が、一番の近道だと改めて感じています。

最後まで読んでいただきありがとうございます。
Twitterもやっているので、興味あればご覧になってください!

参考

・りあクト! TypeScriptで始めるつらくないReact開発 第3版【Ⅰ. 言語・環境編】
・オブジェクト指向でなぜつくるのか 第2版 13章-関数型言語でなぜつくるのか
・JavaScript関数型プログラミング入門
・JavaScriptで関数型プログラミングの入門
・Understand Functional Programming In JavaScript
・What Is Functional Programming?

Select the fields to be shown. Others will be hidden. Drag and drop to rearrange the order.
  • Image
  • SKU
  • Rating
  • Price
  • Stock
  • Availability
  • Add to cart
  • Description
  • Content
  • Weight
  • Dimensions
  • Additional information
  • Attributes
  • Custom attributes
  • Custom fields
Click outside to hide the compare bar
Compare
Compare ×
Let's Compare! Continue shopping