# React勉強会_vol.4 ###### tags:`勉強会中のメモ` ## 関数プログラミングとは * 関数型プログラミングとは、参照透過的な関数を組み合わせることで解決するべき問題に対処していく宣言型のプログラミング * 参照透過性: 同じ入力に対して同じ作用と同じ出力が保証されていること * 命令型 * 手続き型 * オブジェクト指向 * 実際は↑はほぼイコール * 宣言型 * SQL * ☓: どのようにデータベースにアクセスしてデータを取得してくるかという手続き * ○: どんなデータが欲しいかを宣言 ## 関数プログラミングの特徴 * 可変性 * 対になるのは「不変性」 * 破壊的変更がない * 破壊的変更: 以前と異なる結果を引き起こしうる変更のこと * 例でいうと) constで定義した変数に一度値をpushすると、二度と最初の空配列に戻れない * ミュータブルな変数に依存する処理が多ければ多いほど、プログラムの予測可能性が低下してバグが入り込みやすくなる * 端からイミュータブルな変数しか使ってなければそういうことは起きない * 副作用の排除 * 関数型プログラミングでは、代入自体もできるだけ控える傾向にある。最初から代入しなければ壊れるものもない * 関数もその場限りのものならできるだけ無名関数のまま使う * 文でなく式 * 手続き型は「文」 * 左辺→右辺へ評価を渡す。シンプル * 最初から完成形を見据えた上で大雑把なところから絞り込んでいく * 手続き型ではボトムアップ的に積み上げていって最終成果物を完成させる。 * 意図が汲み取りやすい * これ読むべし→[関数型プログラミングを学ぶことの重要性](https://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4/%E9%96%A2%E6%95%B0%E5%9E%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%92%E5%AD%A6%E3%81%B6%E3%81%93%E3%81%A8%E3%81%AE%E9%87%8D%E8%A6%81%E6%80%A7/) ## 関数プログラミングの実例 * よーわからん!宿題にしようw ```javascript= const arr = [1, 2, 3, 4, 5]; console.log(arr.sort((n, m) => n > m ? -1 : 1)); // [ 5, 4, 3, 2, 1 ] // 規定の比較関数 // (n, m) => n > m // (1) n=0 m=1 return: -1 // (2) n=-1 m=2 return: -1 // いや違うよな、、 ``` * `for..of`は`let n`を宣言←これはミュータブル! * `Object`に関しては`Object`がもつメソッドを使う * 本来`インスタンス.メソッド`でありたいけど、、歴史的な理由、、 ## あらためて関数プログラミングとは ### 特徴 1. 名前を持たないその場限りの関数(無名関数)を定義できる 2. 変数に関数を代入できる 3. 関数の**引数として**関数を渡したり、**戻り値として**関数を返すことができる(高階関数) * コールバック関数: 引数として渡される関数のこと 5. 関数に特定の引数を固定した新しい関数を作ることができる(部分適用) 6. 複数の高階関数を合成してひとつの関数にできる(関数合成) * 戻り値の関数もなるたけ無名関数にしておく * よけいな代入を増やさない ### カリー化 * 複数の引数を取る関数を、より少ない引数を取る関数に分割して入れ子にすること ```javascript= // Curried const withMultiple = (n) => { return (m) => n * m; }; withMultiple(2)(4); // 8 ``` ### クロージャ わけわからん、、けど * React ではよくコンポーネントを関数で表現するわけなんだけど、往々にして関数コンポーネントはクロージャであることが多い。 * クロージャの原理を知っておくことはReactを深く理解するのに役立つ ```javascript= // エンクロージャ const counter = () => { let count = 0; const increment = () => { return count += 1; }; return increment; }; ``` ```javascript= let frinedship; if (true) { const he = 'Kakeru'; const saveHim = () => { console.log(`${he} saved`); } }; friendship = saveHim; } friendship(); // Kakeru saved ``` ??? ```javascript= const frinedship = () => { const he = 'Kakeru'; const saveHim = () => { console.log(`${he} saved`); } }; friendship(); ``` ## Promise ```javascript= const isSucceeded = true; const promise = new Promise((resolve, reject) => { if (isSucceeded) { resolve('Success'); //ここの引数が最初のthen()の引数valueとして受け取れる } else { reject(new Error('Failure')); } }); promise.then((value) => { console.log('1.', value); return 'Succees again'; // ここでreturnした値は次のthen()の引数として受け取れる }) .then((value) => { console.log('2.', value); }) .catch((error) => { console.error('3.', error); }) .finally(() => { console.log('4.', 'Completed'); }); ``` ```javascript= import fetch from 'node-fetch'; const getUser = (userId) => fetch(`https://jsonplaceholder.typicode.com/users/${userId}`).then( (response) => { if (!response.ok) { throw new Error(`${response.status} Error`); } else { return response.json(); } }, ); console.log('-- Start --'); getUser(2) .then((user) => { console.log(user); }) .catch((error) => { console.log(error); }) .finally(() => { console.log('-- Completed --'); }); ``` ## メモ * 次回4.1〜4.4目標 * 難しすぎたら都度調整、、