関数型JavaScriptプログラミング



たずめ 

いく぀かの高次関数を取り、それらの関数の郚分的なアプリケヌションを远加し、マップで折り畳みを調敎し、DOMを操䜜するためのJavascript DSLを取埗したす。

人間の蚀葉で 
玔粋で明快なJavaScriptによる関数型プログラミングの簡単で明快な玹介。

Haskell Through Thornsずは異なり、すべおが噛たれ倚すぎる堎合もありたす、棚に眮かれたす。

蚘事を読むこずで、実生掻でのAFの適甚䞍可胜性の神話が明らかになりたす。 同じ問題の解決策をさたざたな芳点から芋るこずができたす。 写真のように。



機胜


簡単な関数定矩から始めたしょう。
function add(a,b){ console.log(a+b); }; 


同じコヌドを異なる方法で曞くこずができたす。
 var add = function(a,b){ console.log(a + b); }; 


Javascriptの倧きな利点の1぀は、その䞭の関数が本栌的なオブゞェクトであるこずです。 真のファヌストクラス垂民。
たずえば、Javaずは異なり、関数はオブゞェクトずは別に存圚できたせん。

䞊蚘の関数は副䜜甚を䌎いたす。぀たり、倖界の状態を倉曎したす。 これは、 console.logを䜿甚しお衚珟されたす。

次に、玔関数の䟋を考えおみたしょう。
 var add = function(a,b){ return a + b; }; 


玔粋な関数は副䜜甚を匕き起こしたせん。 いく぀かのデヌタをそれらに転送するず、デヌタが返されたす。 分析は非垞に簡単です。 テストが簡単です。 倖郚䟝存関係を確認する必芁はありたせん。 したがっお、ほずんどの堎合、副䜜甚のある関数よりも玔粋な関数の方が適しおいたす。
しかし、䞀方で、玔粋な関数のみで構成されるプログラムは実甚的な意味を持ちたせん。 圌女は䜕も読んだり出力したりしたせん。
したがっお、玔粋な機胜を副䜜甚のある機胜から分離するようにプログラムを蚘述し、生掻を簡玠化するこずは論理的です。

したがっお、関数型プログラミングの最初のルヌル- 私たちはファむトクラブに぀いおは語りたせん-玔粋な関数を䜿甚しおいたす。

高階関数


さらに進んでいたす。 関数はオブゞェクトなので、他の関数に枡すこずができたす。 たた、高階関数ずは、関数を返す関数、たたは関数をパラメヌタヌずしお受け取る関数です。

以䞋は、関数も返す関数の簡単な䟋です。

 function makeAdder(base){ return function(num){ return base + num; } } 


そしお、その䜿甚䟋。
 var add2 = makeAdder(2); add2(3); //5 add2(7); //9 


シンプルで明癜。

そしお、これは高次関数のかなりよく知られた䟋です
 var el = document.getElementById("btn"); el.addEventListener("click", function (event){ }); 


パラメヌタずしおのaddEventListenerは関数を受け取りたす。 ぀たり、 addEventListenerは高階関数です。

そしお、むベントが発生するずハンドラヌ関数が呌び出されたす。

おそらく、もう1぀のオプションがより身近なものです。

 $("input[type=submit]").on("clink", function(event){ // ... }); 


たたは、jQueryを䜿甚しおハンドラヌを蚘述するこずもできたす。

だからもう䞀床定矩
FVPは、関数を返すか、パラメヌタヌずしお関数を受け入れる関数です。

サむクル



叀い知人。
サむクルずは、暙準の正面゜リュヌションを意味したす。 このようなもの

 for(var i =0; i<n; ++1){ // } 


たたはそのような
 while(n--){ // ... } // ... 


なぜルヌプを䜿甚するのですか いく぀かの暙準的なナヌスケヌスを芋お、ルヌプが垞に最良の解決策ではないこずを芋おみたしょう。

最初のオプションは、配列ずリストを走査するこずです

 for(var i =0; l< arr.length; i<l; ++i){ console.log(arr[i]); } 


通垞、このバむパスは副䜜甚ず組み合わせお䜿甚​​されたす。 通垞、これらの効果は単玔なコン゜ヌル出力よりも少し䟿利です。

2番目のオプション-リストからデヌタを取埗する

 var names = []; for (var i =0; l= tweeps.length; i< l; ++i) { names.push(tweeps[i].name); } 

この堎合、twitterナヌザヌのリスト。
ルヌプを䜿甚しお、ナヌザヌ名のリストを取埗したす

別の䜿甚䟋は、リスト内のデヌタ集玄です。

 var html = ""; for(var i =0; l = items.length, i<l, i++){ html += '<li>' + items[i] + '</li>'; } this.list.innerHTML = html; 


぀たり、リストデヌタを集蚈し、出力で異なるデヌタ構造を取埗したす。

foreach


ルヌプが垞に最良の゜リュヌションであるずは限らないず蚀いたしたが、代替手段は䜕ですか

同様のサむクルを眮き換えるこずができるものは䜕ですか

 for (var i =1; l = arr.length; i< l; ++i){ console.log(arr[i]); } 


たずえば、 foreach 。

 Array.prototype.forEach arr.forEach(function(item){ console.log(item); }); 


手でリストを実行する代わりに、
配列メ゜ッド。 各芁玠を凊理する関数を枡し、必芁な結果を取埗したす。

しかし、これの根本的な違いは䜕ですか
 for (var i =1; l = arr.length; i< l; ++i){ console.log(arr[i]); } 


そしおこれ

 arr.forEach(function(item){ console.log(item); }); 



残念ながら、JSで関数を蚘述するための構文は十分に冗長なので、曞かれたテキストの量を倧幅に節玄するこずはできたせんでした。

しかし、䜕か他のものがありたす。 コヌドを芋るず、各実装でどのような泚意が払われおいるかがわかりたす。

最初のセクションでは、サむクル自䜓のメカニズムに焊点を圓おたす。 数倀を取埗し、1ず぀増やし、むンデックスで配列芁玠を取埗し、アクションを実行したす。

2番目の䟋は理解しやすいです。 リストの各芁玠で䜕かをしたす。

2番目の䟋では、抜象化のレベルがはるかに高くなっおいたす。 そしお、反察偎から問題の解決にアプロヌチするこずができたす。

したがっお、ルヌプを䜿甚できるものに぀いおは


地図


JavaScriptにある別の関数を芋おみたしょう。

 var names = []; for( var i =0, l= tweeps.length, i< l; ++i){ names.push(tweeps[i].name); } 


これは、リスト倉換に察応する抜象化です。
マップを䜿甚するず、この問題をはるかに簡単に解決できたす。

  //Array.prototype.map var names = tweeps.map(function (tweep){ return tweep.name; }); 


サむクルの説明から䞀時倉数を取り陀きたした。 盎接か぀明確なコヌド。 たた、凊理機胜は十分に短いため、すべおを1行に収めるこずができたす。

 var names = tweeps.map(function(t){return t.name;}); 


私は1行でコヌドを曞くのが奜きではありたせん。 しかし、1行でいく぀のアむデアを衚珟できるかは、APIの衚珟力に぀いお語っおいたす。
Twitterでメンションを探しおください。

 var str = "mentioned by"; for(var i =0; l= tweeps.length; i < l; ++i){ str += tweeps[i].name; if(i< tweeps.length-1) {str += ", "} } 


かなり䞍噚甚な䟋。 むンデックスの䜜成ず配列芁玠の取埗で゚ラヌが発生する堎合がありたす。
この䟋で実際に行うこずを分析したしょう。



マップず結合を䜿甚した曞き換え

 var str = "mentioned by " + tweeps.map(function(t){ return t.name; }).join(", "); 


ミスをする機䌚はずっず少なくなりたした。
しかし、それはもっず良くできたすか :)
オブゞェクトのプロパティにアクセスするために䜿甚する別の高次関数を玹介したしょう。

圌女の小道具ず呌がう

 function prop(name){ return function (object){ return object[name]; } } 


䞀芋、たったく意味がありたせん。 名前をそれに枡したす
そしお、必芁なフィヌルドを匕き出すオブゞェクトが転送される関数を返したす。

ある皮の玛らわしい説明が出たした。 実際のタスクでこの関数を䜿甚しおみたしょう。

 var str = "Mentioned by " + tweeps.map(prop ("name")).join(", "); 


それで、別のワンラむナヌ。 かなり良い衚珟力。 そしお、 prop関数はそれほど圹に立たないわけではありたせん。

枛らす


これは、for、foreach、whileなどの類䌌の構造のstructures祖母です。 この関数はfoldずも呌ばれたす。

プリミティブな䟋からもう䞀床始めたしょう。
 var totalLength = 0; for(var i=0; i< buffers.length; i++){ total.Length += buffers[i].length; } 


バッファの長さを合蚈するだけです。
どのステップに埓うべきですか


Luke関数を䜿甚したす。

たず、 mapを䜿甚しおバッファヌ長を含むリストを取埗したす
 var totalLength = buffers. map(function (buffer) {return buffer.length; }) 


2番目のステップでは、 reduceを適甚しお合蚈を取埗したす。
 var totalLength = buffers. map(function (buffer) {return buffer.length; }). reduce(function(sum, curr){return sum+curr;}, 0); 


reduceに慣れおいない堎合は、非垞に簡単に機胜したす。 バッテリヌ機胜がそれに送信され、各芁玠ずバッテリヌ機胜の初期倀に適甚されたす。

繰り返したすが、耇雑すぎたす。 reduceを単玔なリストに適甚するずどうなるかを芋おみたしょう。

 [10, 5, 15, 10, 10].reduce(function(sum, curr){return sum+curr;}, 0); // [10, 5, 15, 10, 10] // sum curr // => 0, 10 => 10 // => 10, 5 => 15 // => 15, 15 => 30 // => 30, 10 => 40 // => 40, 10 => 50 


したがっお、reduceを䜿甚するず、リストアむテムを簡単に远加できたす。

しかし、すでに䌌たようなものがありたした。 比范しおください。

 function (prev, curr){return prev + curr;} 

そしお
 function add(a,b){ return a+b; } 

したがっお、バッファヌの合蚈長を蚈算するために関数を単玔化できたす。

 var totalLength = buffers. map(function (buffer) {return buffer.length; }). reduce(add, 0); 


今より明確ですか reduceは、 add関数を䜿甚しおリストのすべおの芁玠を単玔に合蚈したす。 合蚈の初期倀はれロです。 䜕がもっず簡単だろうか

しかし、単玔化はこれで終わりではありたせん。 比范する

 function (buffer) {return buffer.length; } 

そしお
 prop("length") 


パンツが回っお......
 var totalLength = buffers. map(prop("length")). reduce(add, 0); 


゚レガントなショヌツ。

もちろん、これを1行で曞くこずができたす

 var totalLength = buffers.map(prop("length")).reduce(add, 0); 


ルヌプの代わりに畳み蟌み瞮小を䜿甚するず、異なる抜象化レベルで考えるこずができたす。 各芁玠のレベルではなく、リストに察しお操䜜を実行したす。

非同期呌び出し



ただし、リストを芁玄するためにリデュヌス別名フォヌルドを䜿甚するこずは、非垞に単玔化された䟋です。 このアむデアははるかに匷力です。 別の䟋を芋おみたしょう。

ブラりザでJavascriptを䜿甚する際の問題の1぀は、すべおが同じスレッドで実行されるため、コヌルバックを䜿甚する必芁があるこずです。

チャレンゞ。

぀たり、次のような関数を䜜成する必芁がありたす。

 combine(["/jquery.js", "/underscore.js", "/backbone.js"], function(content){ // content    ,    . }); 


結合関数の実装を曞きたしょう。 最初-正面アプロヌチ。
 function combine(scripts, callback){ var data []; for(var i =0; l = scripts.length; i< l; ++i){ // .... } } 


スクリプトの堎合、jQuery.ajaxを䜿甚するこずは論理的です。

 function combine(scripts, callback){ var data []; for(var i =0; l = scripts.length; i< l; ++i){ jQuery.ajax({ url: scripts[i], success : function(response){ // .... } }); } } 

このようなコヌドは、サヌバヌぞのリク゚ストが非同期に送信されるため、ブラりザヌの速床を䜎䞋させるこずはありたせん。 ぀たり、実行するず、3぀の䞊列ク゚リが実行されたす。

スクリプトを正垞にダりンロヌドするためのハンドラを䜜成したす。

 function combine(scripts, callback){ var data []; for(var i =0; l = scripts.length; i< l; ++i){ jQuery.ajax({ url: scripts[i], success : function(response){ data[i] = response; if(data.length === scripts.length){ callback(data.join("")); } } }); } } 


機胜の準備ができおいるようです。 しかし、2぀ありたす。
第䞀に、ugい、そしお第二に-それは動䜜したせん。

ここで䜕が問題になりたすか JavaScriptスコヌプを䜿甚。 この蚀語では、スコヌプはブロックベヌスではなく機胜的です。 ぀たり、3぀の関数すべおで倉数iの同じ倀が衚瀺されたす。 サヌバヌからの応答が来る前にサむクルが機胜するため、3぀の機胜はすべおi == 3で機胜したす。
この問題は暙準的な方法で解決されたす-ルヌプ倉数の倀をキャッシュしたす。 しかし、このコヌドがより矎しくなったずは蚀えたせん。

 function combine(scripts, callback){ var data []; for(var i =0; l = scripts.length; i< l; ++i){ (function (i){ jQuery.ajax({ url: scripts[i], success : function(response){ data[i] = response; if(data.length === scripts.length){ callback(data.join("")); } } }); }(i)); } } 


ほずんど動䜜したす。 クロヌゞャヌずトリッキヌな倉数を取り陀くために、foreachを䜿甚できたす

 function combine(scripts, callback){ var data []; scripts.forEach(function(script,i){ jQuery.ajax({ url: scripts[i], success : function(response){ data[i] = response; if(data.length === scripts.length){ callback(data.join("")); } } }); }); } } 


もちろん良いのですが、それでも怖いです。 ずころで、コヌドはただ正しく動䜜したせん。 これは健党な状態に远加できたすが、これにより開発ずその埌のサポヌトにさらに困難が生じたす。

継続合栌スタむル


頭痛を取り陀くために、ラむブラリを䜿甚したす

github.com/caolan/async

仕事では、CPSなどを䜿甚したす。

それは実際よりもずっず悪く聞こえたす。 これは、別の関数をパラメヌタヌずしお受け取る関数であり、最初の関数が終了するず、retrunの代わりにパラメヌタヌ関数を呌び出したす。

目的の結果が埗られるようにjQuery.ajaxをラップしたす。

 function ajax(url, callback){ jQuery.ajax({url: url, success: callback}); } 


この関数はパラメヌタヌずしおコヌルバックを受け取りたすが、゚ラヌハンドラヌに぀いおは説明したせんでした。 実際のコヌドである必芁がありたすが、衚瀺を簡単にするために、忘れおしたいたす。
非同期ラむブラリを䜿甚するずどうなりたすか 次のようになりたす。

 function combine(scripts, callback){ async.map(scripts, ajax, function(contents){ callback(contents.join("")); }); } 


非同期の䞖界で機胜する既補のマップ関数がありたす。 ずころで、珟圚の実装では、前の䟋ずは異なり、スクリプトを接着するための正しい順序が提䟛されたす。

䜕ず比范しおください
 function combine(scripts, callback){ var data []; for(var i =0; l = scripts.length; i< l; ++i){ (function (i){ jQuery.ajax({ url: scripts[i], success : function(response){ data[i] = response; if(data.length === scripts.length){ callback(data.join("")); } } }); }(i)); } } 


mapはすでにプログラムを曞くための自然な方法なので、䞊蚘のコヌドを曞くこずは決しおありたせん。 非同期環境にマップを適応させる方法を考えたす。 非同期ラむブラリがなければ、非同期マップを自分で䜜成したす。

機胜的なアプロヌチにより、物事を芋るのがずっず簡単になりたす。 より矎しい゜リュヌションを実装したす。

関数の郚分的な䜿甚



関数型プログラミングから生たれた別のアむデアであり、正しく調理できれば非垞に䟿利です。

䟋ずしお、DOM芁玠を䜜成したす。
翻蚳者の泚意cull.domは、プロゞェクトの1぀のために䜜成した著者のラむブラリです。ただし、その䞭の機胜は明癜でシンプルです。

 var ul = cull.dom.el("ul"); //document.createElement("ul") ul.nodeType === 1 // true 


プロパティ属性を蚭定するこずもできたす。

 var ul = cull.dom.el("ul", {className: "bands"}); 


そしお子䟛を瀺す

 var li = cull.dom.el("li", "Tom Waits"); var ul = cull.dom.el("ul", {className: "bands"}, li); 


盞互に内郚で䜿甚するず、HTML向けの䜕らかのDSLを取埗できたす。

 va ul = cull.dom.el("ul", className:"bands"}, cull.dom.el("li", "Tom Waits")); 


それでは、関数の郚分的な䜿甚に぀いお説明したしょう。 最初の䟋の1぀を芚えおいたすか

 function makeAdder(base){ return function(num){ return base + num; } } 

2぀の数倀を合蚈する関数を返したす。 もちろん、必芁に応じお、名前付き関数を䜿甚できたす。

 function makeAdder(base){ return function(num){ return add(base, num); } } 


そしお今、 makeAdder関数がadd関数を取り、その匕数の1぀をキャプチャするこずがわかりたす。 匕数の1぀が定数である加算関数を取埗したす

 var add2 = cull.partial(add, 2); add2(5); //7 


興味深い機䌚がありたした-DSLを䜜成しおDOM芁玠をさらに矎しくするこずです。

 var ul = cull.partial(cull.dom.el, "ul"); var li = cull.partial(cull.dom.el, "li"); 


そしお、このようなHTMLリストを䜜成できたす

 var list = ul({className: "bands"}, [li("Diamanda Galas"), li(" "), li("John Zorn")]); 


私のように、文字列倉数のレベルでのプログラミングが嫌いなら、これはあなたの人生を簡玠化する玠晎らしい方法です。 これで、コヌド補完などの䟿利な機胜が远加されたした。 たた、コヌドは通垞のHTMLに非垞に䌌おいたす。
そしお、私たちのアプロヌチは非垞に矎しいため、事前にドキュメントのすべおの芁玠に察しお関数を䜜成できたす。

 ["a", "br", "code", "div", ...].forEach(function(tagName){ cull.dom.el[tagName] = cull.partial(cull.dom.el, tagName); }); 


したがっお、各HTML芁玠に察しお関数を䜜成したす。
もちろん、名前空間は必ずしも完党に䜿甚できるずは限らないため、さらに簡略化したす。

 var e = cull.dom.el; var list = ul({className: "bands"}, [e.li("Pan Sonic"), e.li(" "), e.li("Muslimgauze")]); 


珟圚、グロヌバル倉数ず関数に瞛られおいたせん。これは良いこずです。

機胜構成



簡単なアプリケヌションの別の䟋-アンケヌトです。


各ブロックに答える必芁がありたす。 各ブロックにはいく぀かの質問が含たれおいたす。 1぀のブロックに答えた埌、次のブロックに進みたす。

各ブロックは、質問モヌド、結果モヌド、たたは非アクティブのパネルずしお衚すこずができたす。



各パネルには異なるフィヌルドがありたす。 文字列、数倀、日付。
フィヌルドには、線集モヌドたたは結果モヌドの2぀のモヌドがありたす。

機胜的なアプロヌチを䜿甚しおこの問題にどのようにアプロヌチできるかを芋おみたしょう。

お気に入りのプロップ機胜を芚えおいたすか

 tweeps.map(prop("name")); 


圌女には双子の兄匟機胜がありたす 。

 tweeps.map(func("to.String")); 

オブゞェクトに適甚できる関数を返したす。

アンケヌトの各ブロックの結果を蚈算したしょう

 buildSummary: function(){ return div(this.components.map(func("buildSummary"))); } 


原則は明癜であるべきです。 アンケヌトの各ブロックに察しおbuildSummary関数によっお䜜成された芁玠があるdivを返したす。

この䟋では、各コンポヌネント自䜓がその結果を衚瀺する方法を知っおいたす。 ただし、パネルは結果を特定の方法で衚瀺する必芁がある堎合がありたす。

したがっお、 buildSummaryずgetSummaryの 2぀の関数を䜜成できたす。

1぀は、htmlタグを含む完党なプレれンテヌションを䜜成するこずです。
2番目-必芁な結果を含むオブゞェクトを返したす。

そしお、結果の巧劙な凊理が必芁になるずすぐに、すべおの矎しさが厩れ始めたした。

 buildSummary: function(){ var div = document.createElement("div"); for(var i =0; l=this.components.length; i<l; ++i) { p = document.CreateElement("p"); p.innerHTML = this.components[i].getSummary().text; div.appendChild(p); } return div; } 


ただし、このコヌドを改善するのに十分な機胜指向を既に備えおいたす。 最初の明らかな改善点は、foreachを適甚するこずです。

 buildSummary : function(){ var div = document.createElement("div"); this.components.forEach(function(component){ var p = document.createElement("p"); p.innerHTML = component.getSummary().text; div.appendChild(p); }); return div; } 


ルヌプ倉数を取り陀きたしたが、 mapを䜿甚するこずは可胜ですか

 buildSummary : function(){ return div(this.components.map(function(component){ var p = document.createElement("p"); p.innerHTML = component.getSummary().text; return p; })); } 


短いが理想からはほど遠い。 この匏の䞻な問題
 component.getSummary().text; 


問題は、1぀ではなく、3぀のこずが起こっおいるこずです。
  1. getSummaryによる結果の取埗
  2. テキストプロパティの取埗
  3. 結果をpタグでラップする


いく぀かのマップ関数はどうですか

 buildSummary: function() { return div(this.components. map(function(component){ return component.getSummary(); }).map(function(summary){ return summary.text; }).map(function(text){ var p = document.createElement("p"); p.innerHTML = text; return p; })); } 


機胜的なスタむルはありたすが、恐ろしく芋えたす。 読曞は非垞に䞍䟿です。

しかし、もう䞀床コヌドを芋おみたしょう。 ここには䜕がありたすか

 return component.getSummary(); 


ここでは、オブゞェクトメ゜ッドを呌び出したす。 しかし、このための特別な関数funcを䜜成したした。

 buildSummary: function() { return div(this.components. map(func("getSummary")). map(function(summary){ return summary.text; }).map(function(text){ var p = document.createElement("p"); p.innerHTML = text; return p; })); } 


そしおここに

 function(summary){ return summary.text; } 


オブゞェクトのプロパティにアクセスできたす。 このために、䟿利な機胜もありたす。

 buildSummary: function() { return div(this.components. map(func("getSummary")). map(prop("text")). map(function(text){ var p = document.createElement("p"); p.innerHTML = text; return p; })); } 

最埌のセクションが残った。
 function(text){ var p = document.createElement("p"); p.innerHTML = text; return p; } 


ここで、DOM芁玠を䜜成し、その内郚プロパティを蚭定したす。 DSLにも䌌たようなものがありたすよね

 buildSummary: function() { return div(this.components. map(func("getSummary")). map(prop("text")). map(p)); } 

今ではほずんど矎しいです。 ただし、泚意点が1぀ありたす。 リストで3぀のパスを行いたす。 堎合によっおは、これは正垞かもしれたせんが、党䜓的にいくぶん最適ではありたせん。 䜕ができたすか

機胜の構成を䜿甚したす。 1぀の関数に3぀の関数を実行させたいのです。

 var summarize = compose( [p, prop("text"), func("getSummary")]); 


䜜成をどのように実装したすか


郚分的に。 たず、倚くのコヌドを蚘述しないように同矩語を䜜成したしょう。

 var callGetSummary = func("getSummary"); var getText = prop("text"); var summarize = compose([p, getText, callGetSummary]); 


すべおがシンプルで明癜です。 さらに進んでいたす。 サマリ関数を呌び出すずどうなるか芋おみたしょう。

最初のステップ


 var callGetSummary = func("getSummary"); var getText = prop("text"); var summarize = compose([p, getText, callGetSummary]); // summarize(obj); // => callGetSummary(obj) 

オブゞェクトはリストの最埌の関数、぀たりgetSummaryに転送されたす。 タむプsummaryのオブゞェクトを返したす。 そしお、このオブゞェクトは次の関数getTextに枡されたす

第二段階


 var callGetSummary = func("getSummary"); var getText = prop("text"); var summarize = compose([p, getText, callGetSummary]); // summarize(obj); // => getText(callGetSummary(obj)) 


2番目のステップの結果ずしお、 textプロパティに含たれる文字列を取埗したす。 その埌、行はpOM DOMオブゞェクトを䜜成する関数に分類されたす。

第䞉段階


 var callGetSummary = func("getSummary"); var getText = prop("text"); var summarize = compose([p, getText, callGetSummary]); // summarize(obj); // => p(getText(callGetSummary(obj))) 


これは、パラメヌタヌが関数から関数に順番に枡される堎合の単玔な構成の䟋です。パラメヌタヌが各関数に枡されるずきに構成を䜜成でき、出力は結果のリストになりたす。たたは䜕か他のもの。

それでは、蟛抱匷い䟋に戻りたしょう。

 builSummary: function() { var summarize = compose( [p, prop("text"), func("getSummary")]); return div(this.components.map(summarize)); } 


最初に、結果を蚈算するための関数を䜜成したした。そしお、マップを適甚したした。
同時に、summary関数はどのオブゞェクトで動䜜するかを絶察に知らないこずに泚意しおください。これらは、compose関数を介しおのみ接続する3぀の異なる抜象化です。したがっお、集蚈を別の゚ンティティに䜜成できたす。

 var summarize = compose( [p, prop("text"), func("getSummary")]); // ... builSummary: function() { return div(this.components.map(summarize)); } 


かっこよくおきれいに芋えたすが、パフォヌマンスはどうですか

パフォヌマンスの問題



for — 5M
forEach — 1,5M
reduce — 1.5M

DOM — 50K

, DOM. , , — . .

おわりに




(map, reduce).
.
.

PS cjohansen.no/talks/2012/javazone
PPS ?

Source: https://habr.com/ru/post/J154105/


All Articles