javascript之Partial Application學(xué)習(xí)
更新時(shí)間:2013年01月10日 09:05:50 作者:
在數(shù)學(xué)中,一個(gè)函數(shù)是描述每個(gè)輸入值對(duì)應(yīng)唯一輸出值的這種對(duì)應(yīng)關(guān)系,符號(hào)為 f(x)。例如,表達(dá)式 f(x)=x2表示了一個(gè)函數(shù) f,其中每個(gè)輸入值x都與唯一輸出值x2相聯(lián)系
這一次來學(xué)習(xí)一下Partial Application。我們先看一下函數(shù)的介紹,在維基上有簡(jiǎn)單的介紹:
在數(shù)學(xué)中,一個(gè)函數(shù)是描述每個(gè)輸入值對(duì)應(yīng)唯一輸出值的這種對(duì)應(yīng)關(guān)系,符號(hào)為 f(x)。例如,表達(dá)式 f(x)=x2表示了一個(gè)函數(shù) f,其中每個(gè)輸入值x都與唯一輸出值x2相聯(lián)系。
因此,如果一個(gè)輸入值為3,那么它所對(duì)應(yīng)的輸出值為9。而g(x,y) = xy有兩個(gè)參量x和y,以乘積xy為值。上面描述了函數(shù)(為方便假設(shè)x,y都是int),并且給出了函數(shù)的兩個(gè)例子,先換一種方式來看,f(x)可以表示為:x -> y(x2),即經(jīng)經(jīng)過f到x2的映射,寫成 int -> int。
接受一個(gè)int 返回一個(gè)int。再看g(x,y)可以表示為:x -> y -> z(xy)。即x,y經(jīng)過g的映射到z,寫成 int -> int -> int。我們看g(x,y)函數(shù),用javascript來實(shí)現(xiàn)一下:
function g(x,y){
return x*y;
}
很完美啊,很接近數(shù)學(xué)定義。它依次接受兩個(gè)參數(shù),x與y。并且返回它們兩個(gè)的乘積。但是當(dāng)x是個(gè)常數(shù),比如x=n(n是一個(gè)自然數(shù))。那么g(n,y)=ny。這就變成一個(gè)常數(shù)與一個(gè)變量的乘積,它接受一個(gè)參數(shù)y返回ny,即y -> z(ny) 的映射,寫成 int -> int。因此,我們可以這樣來理解上面的工作,g(x,y)是接受一個(gè)參數(shù)int,并且返回一個(gè)函數(shù) int ->int 。這個(gè)返回的函數(shù)只接受一個(gè)int 并且返回一個(gè)int。來用javascript表示一下:
var h = g(2);
這里的h表示函數(shù)h(y)=2y。這樣就有h(5)=10,h(13)=26等。
h(5);
h(13);
這個(gè)技術(shù)是把需要多個(gè)參數(shù)的函數(shù)形式轉(zhuǎn)變?yōu)榻邮軉蝹€(gè)參數(shù)的函數(shù)鏈,它通常叫做Curring,這是為了紀(jì)念Haskell Curry而起的名字,但他并不是第一個(gè)提出的1。但是很遺憾的是javascript并不支持這樣的特性。所以要實(shí)現(xiàn)這樣的特性需要做一些工作,這些工作并不復(fù)雜。主要是把參數(shù)存儲(chǔ)起來,等待調(diào)用函數(shù)鏈上的下一個(gè)函數(shù)時(shí)拿出前邊參數(shù)繼續(xù)傳遞給鏈上的下一個(gè)函數(shù),直到最后得到返回值。先看一下下面的代碼:
function atarr(a,index){
var index=index||0,args = new Array(a.length - index);
for(var i in a){
if(i>=index) args[i-index]=a[i];
}
return args;
}
function m(scope,fn){
if(arguments.length<3) return fn.call(scope);
var p = atarr(arguments,2);
return function(){
var args = atarr(arguments);
return fn.apply(scope,p.concat(args));
}
}
測(cè)試代碼:
var plus = function(a,b){
return a+b;
};
var plus2 = m(null,plus,2);
console.log(plus2(10));
console.log(plus2(0));
//結(jié)果
12
2
這樣我們的目標(biāo)已經(jīng)實(shí)現(xiàn)啦。在上面的atarr函數(shù)是將arguments對(duì)象中指定位置開始的參數(shù)取出并且保存到一個(gè)數(shù)組中。m函數(shù)就是主角,它完成了前面定義的任務(wù),實(shí)現(xiàn)了保存函數(shù)鏈上的參數(shù)并且返接受余下參數(shù)的函數(shù)。測(cè)試代碼中的plus函數(shù)原先接受a,b兩個(gè)參數(shù)并返回a與b之和,即 int -> int -> int,而plus2則變成了接受一個(gè)參數(shù)b與2相加,并返回2與b之和,即 int -> int。
通過上面的一些工作,我們實(shí)現(xiàn)了javascript中的Partial Application,在dojo框架中hitch2實(shí)現(xiàn)了域綁定和partial。有興趣可以讀一下它的源碼,也是非常簡(jiǎn)單明了的。
在數(shù)學(xué)中,一個(gè)函數(shù)是描述每個(gè)輸入值對(duì)應(yīng)唯一輸出值的這種對(duì)應(yīng)關(guān)系,符號(hào)為 f(x)。例如,表達(dá)式 f(x)=x2表示了一個(gè)函數(shù) f,其中每個(gè)輸入值x都與唯一輸出值x2相聯(lián)系。
因此,如果一個(gè)輸入值為3,那么它所對(duì)應(yīng)的輸出值為9。而g(x,y) = xy有兩個(gè)參量x和y,以乘積xy為值。上面描述了函數(shù)(為方便假設(shè)x,y都是int),并且給出了函數(shù)的兩個(gè)例子,先換一種方式來看,f(x)可以表示為:x -> y(x2),即經(jīng)經(jīng)過f到x2的映射,寫成 int -> int。
接受一個(gè)int 返回一個(gè)int。再看g(x,y)可以表示為:x -> y -> z(xy)。即x,y經(jīng)過g的映射到z,寫成 int -> int -> int。我們看g(x,y)函數(shù),用javascript來實(shí)現(xiàn)一下:
復(fù)制代碼 代碼如下:
function g(x,y){
return x*y;
}
很完美啊,很接近數(shù)學(xué)定義。它依次接受兩個(gè)參數(shù),x與y。并且返回它們兩個(gè)的乘積。但是當(dāng)x是個(gè)常數(shù),比如x=n(n是一個(gè)自然數(shù))。那么g(n,y)=ny。這就變成一個(gè)常數(shù)與一個(gè)變量的乘積,它接受一個(gè)參數(shù)y返回ny,即y -> z(ny) 的映射,寫成 int -> int。因此,我們可以這樣來理解上面的工作,g(x,y)是接受一個(gè)參數(shù)int,并且返回一個(gè)函數(shù) int ->int 。這個(gè)返回的函數(shù)只接受一個(gè)int 并且返回一個(gè)int。來用javascript表示一下:
復(fù)制代碼 代碼如下:
var h = g(2);
這里的h表示函數(shù)h(y)=2y。這樣就有h(5)=10,h(13)=26等。
復(fù)制代碼 代碼如下:
h(5);
h(13);
這個(gè)技術(shù)是把需要多個(gè)參數(shù)的函數(shù)形式轉(zhuǎn)變?yōu)榻邮軉蝹€(gè)參數(shù)的函數(shù)鏈,它通常叫做Curring,這是為了紀(jì)念Haskell Curry而起的名字,但他并不是第一個(gè)提出的1。但是很遺憾的是javascript并不支持這樣的特性。所以要實(shí)現(xiàn)這樣的特性需要做一些工作,這些工作并不復(fù)雜。主要是把參數(shù)存儲(chǔ)起來,等待調(diào)用函數(shù)鏈上的下一個(gè)函數(shù)時(shí)拿出前邊參數(shù)繼續(xù)傳遞給鏈上的下一個(gè)函數(shù),直到最后得到返回值。先看一下下面的代碼:
復(fù)制代碼 代碼如下:
function atarr(a,index){
var index=index||0,args = new Array(a.length - index);
for(var i in a){
if(i>=index) args[i-index]=a[i];
}
return args;
}
function m(scope,fn){
if(arguments.length<3) return fn.call(scope);
var p = atarr(arguments,2);
return function(){
var args = atarr(arguments);
return fn.apply(scope,p.concat(args));
}
}
測(cè)試代碼:
復(fù)制代碼 代碼如下:
var plus = function(a,b){
return a+b;
};
var plus2 = m(null,plus,2);
console.log(plus2(10));
console.log(plus2(0));
//結(jié)果
12
2
這樣我們的目標(biāo)已經(jīng)實(shí)現(xiàn)啦。在上面的atarr函數(shù)是將arguments對(duì)象中指定位置開始的參數(shù)取出并且保存到一個(gè)數(shù)組中。m函數(shù)就是主角,它完成了前面定義的任務(wù),實(shí)現(xiàn)了保存函數(shù)鏈上的參數(shù)并且返接受余下參數(shù)的函數(shù)。測(cè)試代碼中的plus函數(shù)原先接受a,b兩個(gè)參數(shù)并返回a與b之和,即 int -> int -> int,而plus2則變成了接受一個(gè)參數(shù)b與2相加,并返回2與b之和,即 int -> int。
通過上面的一些工作,我們實(shí)現(xiàn)了javascript中的Partial Application,在dojo框架中hitch2實(shí)現(xiàn)了域綁定和partial。有興趣可以讀一下它的源碼,也是非常簡(jiǎn)單明了的。
您可能感興趣的文章:
相關(guān)文章
js代碼實(shí)現(xiàn)的加入收藏效果并兼容主流瀏覽器
這篇文章主要介紹了js代碼實(shí)現(xiàn)的加入收藏效果并兼容主流瀏覽器,需要的朋友可以參考下2014-06-06JavaScript Date對(duì)象使用總結(jié)
js 日期對(duì)象的一些方法總結(jié)2009-05-05JS動(dòng)態(tài)給對(duì)象添加事件的簡(jiǎn)單方法
下面小編就為大家?guī)硪黄狫S動(dòng)態(tài)給對(duì)象添加事件的簡(jiǎn)單方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-07-07JS實(shí)現(xiàn)移動(dòng)端點(diǎn)擊按鈕復(fù)制文本內(nèi)容
本文通過實(shí)例代碼給大家介紹了移動(dòng)端點(diǎn)擊按鈕復(fù)制文本內(nèi)容 ,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07JS跨域解決方案之使用CORS實(shí)現(xiàn)跨域
正常使用AJAX會(huì)需要正??紤]跨域問題,所以偉大的程序員們又折騰出了一系列跨域問題的解決方案,如JSONP、flash、ifame、xhr2等等。本文給大家介紹JS跨域解決方案之使用CORS實(shí)現(xiàn)跨域,感興趣的朋友參考下吧2016-04-04javascript 驗(yàn)證碼生成代碼 推薦學(xué)習(xí)
非常不錯(cuò)的用javascript實(shí)現(xiàn)的驗(yàn)證碼實(shí)現(xiàn)代碼。2009-07-07js 動(dòng)態(tài)給元素添加、移除事件的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄猨s 動(dòng)態(tài)給元素添加、移除事件的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-07-07JavaScript常用語句循環(huán),判斷,字符串換數(shù)字
這篇文章主要介紹了JavaScript常用語句主要包括對(duì)循環(huán),判斷,字符串換數(shù)字相關(guān)資料的介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下具體內(nèi)容2021-12-12