blog

JS高次プログラミング・アプリケーション

Compose 組み合わせ関数、多層関数入れ子呼び出しの平坦化。...

Sep 26, 2020 · 4 min. read
シェア

シングルケース設計パターン

コンセプト:現在のトランザクションの関連機能を管理するための別のインスタンスは、機能のグループ化の実装に似ており、この時点でobjなどという名前のオブジェクトと呼ばれるだけでなく、名前空間として知られていません。

シングルトンパターンのクロージャに基づく制御は、早期のモジュール分割を実現する方法として、高レベルシングルトンパターンと呼ばれています;

let module = (function(){
 function query(){}
 function tools(){}
 return {
 name:'test',
 tools:tools
 }
})();

不活性思考

//以下の方法は、一度だけ判定を行うだけで、何度か判定を繰り返すために何度も実行する必要はない。
function getCss(el,attr){
 //'name' in obj--現在の属性名がobjの属性であるかどうかを検出する。
 if('getComputedStyle' in window){
 getCss = function (el,attr){
 return window.getComputedStyle(el)[attr];
 }
 }else{
 getCss = function (el,attr){
 return el.currentStyle[attr];
 }
 }
 return getCss(el,attr);
}
getCss(document.body,'margin');
getCss(document.body,'padding');
getCss(document.body,'width');

正誤表関数

コンセプト:クロージャの保存メカニズムを使って、ある情報をあらかじめ保存しておきます;

let res = fn(1,2)(3);
console.log(res); //=>6 1+2+3

回答:fn(1,2)が最初に実行され、次に...が実行されます。そして、fn(1,2)は実行される関数を返す必要があるので、return function(){...}となります。

function fn(...outer){
 return function anonymous(...inner){
 let params = outer.concat(inner); //外側の関数と内側の関数から渡される値はすべて一緒に結合される。
 return params.reduce((n,item)=>{
 return n + item; 
 },0)
 }
}

知識の拡張:削減

//2つ目の実パラメータ値を渡さない
let arr = [1,2,3,4,5];
let res = arr.reduce((n,item)=>{
 console.log(n,item); 
 //最初の出力:1 2 コールバック関数実行の最初のトリガー、nは最初の項目、itemは2番目の項目である。
 //2回目の出力:3 3回目のコールバック関数の実行がトリガーされたとき、nは前のコールバック関数の戻り結果であり、itemはitemの配列を後方にトラバースし続ける
 //第3の出力:6 4 ...
 //第4の出力:10 5 コールバック関数が実行されるm回目のトリガー、nはm-1番目のコールバック関数の戻り結果である。
 return n+item; //returnメッセージは、次のコールバック関数の実行結果として使用される。
})
//2つ目の実パラメータ値を渡す
let arr = [1,2,3,4,5];
let res = arr.reduce((n,item)=>{
 console.log(n,item); 
 //最初の出力:0 1 最初のトリガーとなるコールバック関数の実行、nは2番目のパラメータ値、itemは配列の最初の項目である。
 //最初の出力:1 2 2番目のトリガーはコールバック関数の実行、nは前のコールバック関数の戻り結果、itemは配列itemを後方にトラバースし続ける
 //番目の出力:3 3 ...
 //第3の出力:6 4 ...
 //第4の出力:10 5 コールバック関数が実行されるm回目のトリガー、nはm-1番目のコールバック関数の戻り結果である。
 return n+item; //returnメッセージは、次のコールバック関数の実行結果として使用される。
},0)

コールバック関数:ある関数を別の関数に値として渡し、その関数を別の関数内で実行します;

  • 関数型プログラミング:結果を重視し、プロセスは気にせず、他の人に任せること;
  • コマンドプログラミング:プロセスに重点を置き、そのプロセスを自分で実行する必要があります;

compose

Composeは関数を組み合わせて、ネストした関数呼び出しの複数のレイヤーをフラットにします。

/*
 ---------------------------------------------Problem description ---------------------------------------------
 関数型プログラミングでは、関数の組み合わせという非常に重要な概念がある。実際、関数の組み合わせとは、データをパイプラインのようにつないで処理し、パイプラインを通して最終的な結果を得る機能である。 例えば
 const add1 = (x) => x + 1;
 const mul3 = (x) => x * 3;
 const div2 = (x) => x / 2;
 div2(mul3(add1(add1(0)))); //=>3
 また、このような書き方は明らかに可読性が低すぎる。コンポーズ関数を作り、任意の数の関数をパラメータとして受け取り、コンポーズも関数を返すようにすれば、以下のような効果が得られる:
 const operate = compose(div2, mul3, add1, add1)
 operate(0) //=>div2))に相当する。) 
 operate(2) //=>div2))に相当する。)
 要するに、composeはf)と同じようなものである。 
*/
/*
	------------------------------------------Analyse -------------------------------------------------
	compose関数は実行後も実行され続け、コンポーズ関数は関数を返す。
*/
const fn1 = x => x+10;
const fn2 = x => x-10;
const fn3 = x => x*10;
const fn4 = x => x/10;
function compose(...funcs){
 //funcs:順番に実行される関数を格納する。 [fn1,fn3,fn2,fn4]
 return function anonymous(...args){
 //args:最初の関数の実行に必要なパラメータ情報を保存する。 [10]
 
 if(funcs.length===0) return args;
 if(funcs.length===1) return funcs[0](...args);
 return funcs.reduce((n,item)=>{
 //最初のn:最初の関数が実際のパラメータ項目を実行する。
 //つ目のn:最後の項目実行の戻り値を、次の関数実行に渡される実パラメーターとする。
 return Array.isArray(n) ? item(...n) : item(n) ;
 },args)
 }
}
let res = compose(fn1,fn3,fn2,fn4)(10);
console.log(res);
Read next

LeetCode002-2つの数字を足す-中

要求された2つの和のノード数がわからないので、whileループを選択します。いずれかのノードがnullでない限り、ループは継続します。

Sep 24, 2020 · 3 min read