javascript
javascript之Partial Application
這一次來學習一下Partial Application。我們先看一下函數的介紹,在維基上有簡單的介紹:
在數學中,一個函數是描述每個輸入值對應唯一輸出值的這種對應關系,符號為 f(x)。例如,表達式 f(x)=x2表示了一個函數 f,其中每個輸入值x都與唯一輸出值x2相聯系。因此,如果一個輸入值為3,那么它所對應的輸出值為9。而g(x,y) = xy有兩個參量x和y,以乘積xy為值。
上面描述了函數(為方便假設x,y都是int),并且給出了函數的兩個例子,先換一種方式來看,f(x)可以表示為:x -> y(x2),即經經過f到x2的映射,寫成 int -> int。接受一個int 返回一個int。再看g(x,y)可以表示為:x -> y -> z(xy)。即x,y經過g的映射到z,寫成 int -> int -> int。我們看g(x,y)函數,用javascript來實現一下:
function g(x,y){return x*y; }很完美啊,很接近數學定義。它依次接受兩個參數,x與y。并且返回它們兩個的乘積。但是當x是個常數,比如x=n(n是一個自然數)。那么g(n,y)=ny。這就變成一個常數與一個變量的乘積,它接受一個參數y返回ny,即y -> z(ny) 的映射,寫成 int -> int。因此,我們可以這樣來理解上面的工作,g(x,y)是接受一個參數int,并且返回一個函數 int ->int 。這個返回的函數只接受一個int 并且返回一個int。來用javascript表示一下:
var h = g(2);這里的h表示函數h(y)=2y。這樣就有h(5)=10,h(13)=26等。
h(5); h(13);這個技術是把需要多個參數的函數形式轉變為接受單個參數的函數鏈,它通常叫做Curring,這是為了紀念Haskell Curry而起的名字,但他并不是第一個提出的1。但是很遺憾的是javascript并不支持這樣的特性。所以要實現這樣的特性需要做一些工作,這些工作并不復雜。主要是把參數存儲起來,等待調用函數鏈上的下一個函數時拿出前邊參數繼續傳遞給鏈上的下一個函數,直到最后得到返回值。先看一下下面的代碼:
1 function atarr(a,index){ 2 var index=index||0,args = new Array(a.length - index); 3 for(var i in a){ 4 if(i>=index) args[i-index]=a[i]; 5 } 6 return args; 7 } 8 function m(scope,fn){ 9 if(arguments.length<3) return fn.call(scope); 10 var p = atarr(arguments,2); 11 12 return function(){ 13 var args = atarr(arguments); 14 return fn.apply(scope,p.concat(args)); 15 } 16 }測試代碼:
1 var plus = function(a,b){ 2 return a+b; 3 }; 4 var plus2 = m(null,plus,2); 5 console.log(plus2(10)); 6 console.log(plus2(0)); 7 8 //結果 9 12 10 2 這樣我們的目標已經實現啦。在上面的atarr函數是將arguments對象中指定位置開始的參數取出并且保存到一個數組中。m函數就是主角,它完成了前面定義的任務,實現了保存函數鏈上的參數并且返接受余下參數的函數。測試代碼中的plus函數原先接受a,b兩個參數并返回a與b之和,即 int -> int -> int,而plus2則變成了接受一個參數b與2相加,并返回2與b之和,即 int -> int。
通過上面的一些工作,我們實現了javascript中的Partial Application,在dojo框架中hitch2實現了域綁定和partial。有興趣可以讀一下它的源碼,也是非常簡單明了的。
1.Curring:來自維基百科 Curring。
2.來自dojo toolkit,參見hitch。
轉載于:https://www.cnblogs.com/mike442144/archive/2013/01/10/2853940.html
總結
以上是生活随笔為你收集整理的javascript之Partial Application的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux文件系统与日志
- 下一篇: 统计字符串中某个字符的个数