摘要:返回一個(gè)函數(shù)作為結(jié)果。利用函數(shù)將值的集合合并成一個(gè)值,該函數(shù)接受一個(gè)累積和本次處理的值。集合中心編程函數(shù)式編程對(duì)于需要操作集合中元素的任務(wù)非常有用。
函數(shù)是一等公民本文章記錄本人在學(xué)習(xí) 函數(shù)式 中理解到的一些東西,加深記憶和并且整理記錄下來(lái),方便之后的復(fù)習(xí)。
"一等"這個(gè)術(shù)語(yǔ)通常用來(lái)描述值。當(dāng)函數(shù)被看作“一等公民”時(shí),那它就可以去任何值可以去的地方,很少有限制。比如那數(shù)值和函數(shù)做比較。
函數(shù)與數(shù)字一樣可以存儲(chǔ)為變量
var fortytwo = function () { return 42; };
函數(shù)與數(shù)字一樣可以存儲(chǔ)為數(shù)組的一個(gè)元素。
var fortytwos = [42, function () { return 42; }];
函數(shù)與數(shù)字一樣可以作為對(duì)象的成員變量。
var fortytows = {number: 42, fun: function () {}}
函數(shù)與數(shù)字一樣可以在使用的時(shí)候直接創(chuàng)建出來(lái)。
42 + (function () { return 42; })();
函數(shù)與數(shù)字一樣可以被傳遞給另一個(gè)函數(shù)。
function weirdAdd(n, f) { return n + f() }; weirdAdd(42, function() { return 42; });
函數(shù)與數(shù)字一樣可以被另一個(gè)函數(shù)返回。
return 42; return function() { return 42; };
關(guān)于最后兩點(diǎn),其實(shí)就是對(duì)“高階”函數(shù)的定義,也就是:
以一個(gè)函數(shù)作為參數(shù)。
返回一個(gè)函數(shù)作為結(jié)果。
從上面舉的栗子可以看來(lái)。做為“一等公民”的函數(shù)就會(huì)擁有類型數(shù)字的性質(zhì)。
Applicative 編程簡(jiǎn)單來(lái)說(shuō)Applicative編程定義為函數(shù)A作為參數(shù)提供給函數(shù)B。在Applicative編程三個(gè)典型的例子是:mao、reduce和filter。
看下面栗子:
var nums = [1, 2, 3, 4, 5]; // 數(shù)組的所有項(xiàng)都 * 2 function doubleAll(array) { return _.map(array, function (n) { return * 2 }); } // 數(shù)組的所有項(xiàng)相加,返回 sum / _.size(array) function average(array) { var sum = _.reduce(array, function (a, b) { return a + b }); return sum / _.size(array); } // 塞選數(shù)組中的偶數(shù)項(xiàng),并且返回一個(gè)新的數(shù)組 function onlyEven(array) { return _.filter(arr, function (n) { return (n % 2) === 0; }); } doubleAll(nums); // [2, 4, 6, 8, 10]; average(nums); // 3 only(nums); / [2,4]
看了上面的栗子,能看出mao、reduce和filter會(huì)在某一個(gè)地方最終調(diào)用作為參數(shù)的匿名函數(shù)。實(shí)際上,這些函數(shù)的語(yǔ)義可以由這個(gè)調(diào)用關(guān)系來(lái)定義:
_.map()遍歷集合并對(duì)每一個(gè)值調(diào)用一個(gè)函數(shù),返回結(jié)果的集合。
_.reduce利用函數(shù)將值的集合合并成一個(gè)值,該函數(shù)接受一個(gè)累積和本次處理的值。
_.filter對(duì)集合每一個(gè)值調(diào)用一個(gè)謂詞函數(shù)(也就是返回true或者false的函數(shù)),抽取謂詞函數(shù)返回true的值的集合。
集合中心編程函數(shù)式編程對(duì)于需要操作集合中元素的任務(wù)非常有用。新建一個(gè)簡(jiǎn)單的對(duì)象:{a: 1, b: 2},然后拿_.map()使用_.identity()函數(shù)(返回其參數(shù)的函數(shù))。例如:
_.map({a: 1, b: 2}, _.identity); // [1, 2];
從集合為中心的角度看,Underscore和一般函數(shù)式編程所提倡的是要建立一個(gè)統(tǒng)一的處理方式,使我們可以重用一套綜合的函數(shù)。
定義幾個(gè) Applicative 函數(shù)用 100 個(gè)函數(shù)操作一個(gè)數(shù)據(jù)結(jié)構(gòu),必用 10 個(gè)函數(shù)操作 10 個(gè)數(shù)據(jù)結(jié)構(gòu)要好。
Underscore提供了許多的applicative函數(shù),有興趣的可以去閱讀一下API以及源碼。通過(guò)小栗子來(lái)看看如何創(chuàng)建一個(gè)applicative函數(shù):
// 一個(gè)簡(jiǎn)單、接受一定數(shù)量的參數(shù)并連接它們的函數(shù)并不是 applicative。 function cat() { var head = _.frist(arguments); if (existy(head)) return head.concat.apply(head, _.reset(arguments)); else return []; } cat([1, 2, 3], [4, 5], [6, 7, 8]); // [1, 2, 3, 4, 5, 6, 7, 8]
接著繼續(xù)定義一個(gè)construct函數(shù),construct函數(shù)接受一個(gè)元素和一個(gè)數(shù)組,并且cat將元素防止在數(shù)組前方:
function construct(head, tail) { return cat([head], _.toArray(tail))); } construct(42, [1, 2, 3]); // [42, 1, 2, 3]
雖然上面的construct函數(shù)中使用到了cat,但是它并沒(méi)有將cat作為參數(shù)傳入,所以不符合要求。
在定義一個(gè)函數(shù)mapcat:
function mapcat(fun, coll) { return cat.apply(null, _.map(coll, fun); } mapcat(function (e) { return construct(e, [","]); }, [1,2,3]); // [1, ",", 2, ",", 3, ","]
mapcat函數(shù)接受一個(gè)函數(shù)fun,與_.map用了相同的方式,對(duì)給定集合中的每個(gè)元素進(jìn)行調(diào)用。這種fun的使用是mapcat的applicative本質(zhì)。
當(dāng)映射函數(shù)返回一個(gè)數(shù)組,mapcat可以將其展平。接著繼續(xù)定義butLast和interpose函數(shù):
function butLast(coll) { return _.toArray(coll).slice(0, -1); } function interpose(inter, coll) { return butLast(mapcat(function (e) { return construct(e, [inter]); }, coll)); } interpose(",", [1, 2, 3]); // [1, ",", 2, ",", 3]
數(shù)據(jù)思考用較低級(jí)別的函數(shù)來(lái)逐步定義和使用離散功能。
在js中,對(duì)象類型是非常強(qiáng)大的,但與其一起工作的工具并不完全是函數(shù)式的。相反,用js對(duì)象更常用的模式是,以多態(tài)調(diào)度為目的來(lái)附加方法。
雖然把js對(duì)象當(dāng)成數(shù)據(jù)映射來(lái)操作和訪問(wèn)的工具本身很少,但是幸好有Underscore提供了有用的一系列操作。其中有:_.keys,_.values和_.pluck。有興趣的可以去看看API文檔。
拿_.pluck函數(shù)和_.omit函數(shù)做一個(gè)小栗子:
var person = {name: "Romy", token: "j3983ij", password: "trigress"}; var info = _.omit(person, "token", "password"); // {name: "Romy"} var creds = _.pick(person, "token", "password"); // {token: "j3983ij", password: "trigress"}
上面的栗子是,使用相同的“危險(xiǎn)”鍵:token和password,_.onmit函數(shù)接受一個(gè)黑名單,從對(duì)象中刪除鍵,而_.pick根據(jù)白名單保留相應(yīng)鍵,且都不會(huì)修改原來(lái)的對(duì)象。
如果使用過(guò)了Underscore函數(shù)來(lái)操作對(duì)象,你會(huì)覺(jué)得非常類似與SQL,都是根據(jù)一個(gè)強(qiáng)大的聲明規(guī)約進(jìn)行過(guò)濾和處理邏輯數(shù)據(jù)表。
總結(jié)最后總結(jié)一下一等函數(shù):
它們可以存儲(chǔ)在變量中。
它們可以被存儲(chǔ)在數(shù)組中的插槽中。
它們可以存儲(chǔ)在對(duì)象的字段中。
它們可以根據(jù)需求來(lái)創(chuàng)建。
它們可以被傳遞到其他函數(shù)中。
它們可以被其他函數(shù)返回。
一等函數(shù)的意思就是以上的幾點(diǎn)了。可以簡(jiǎn)單它擁有數(shù)值一樣的性質(zhì)。
在總結(jié)一下applicative編程,簡(jiǎn)單來(lái)說(shuō)就是函數(shù)A作為參數(shù)提供給函數(shù)B。_.map、_.reduce和_.filter就是最好的例子。
有啥不對(duì),請(qǐng)斧正!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/85874.html
摘要:不純的函數(shù)充滿的不確定性,在函數(shù)式編程中要盡量避免它。在以后的函數(shù)式編程中還會(huì)不斷的遇見(jiàn)它的。 一.為什么需要柯里化(curry函數(shù)) 1.先簡(jiǎn)單的介紹一下純函數(shù) 在函數(shù)式編程中純函數(shù)是其最基本的思想,所謂純函數(shù)就是一個(gè)相對(duì)不受外界影響(之所以說(shuō)相對(duì),是因?yàn)橛械臅r(shí)候需要和外界溝通,函數(shù)沒(méi)法保持所謂真正的純,但后面會(huì)有方法來(lái)解決).在高中數(shù)學(xué)中都學(xué)過(guò),函數(shù)是一種映射關(guān)系,在y=f(x)這...
摘要:在近期看到了函數(shù)式編程這本書預(yù)售的時(shí)候就定了下來(lái)。主要目的是個(gè)人目前還是不理解什么是函數(shù)式編程。且和現(xiàn)在在學(xué)習(xí)函數(shù)式編程有莫大的關(guān)系。加速大概了解了函數(shù)式編程之后??偨Y(jié)看完了第一章也是可以小結(jié)一下的函數(shù)式編程。 本文章記錄本人在學(xué)習(xí) 函數(shù)式 中理解到的一些東西,加深記憶和并且整理記錄下來(lái),方便之后的復(fù)習(xí)。 在近期看到了《JavaScript函數(shù)式編程》這本書預(yù)售的時(shí)候就定了下...
摘要:設(shè)定瀏覽器屬性的屬性的方法叫做駝峰式命名是函數(shù)名方法名和對(duì)象屬性名的命名首選格式。由瀏覽器預(yù)先定義的對(duì)象被稱為宿主對(duì)象。在給某個(gè)元素添加了事件處理函數(shù)后,一旦事件發(fā)生,相應(yīng)的代碼就會(huì)執(zhí)行。 1.JavaScript是一個(gè)使網(wǎng)頁(yè)具有交互能力的程序設(shè)計(jì)語(yǔ)言。 2.設(shè)定瀏覽器屬性的屬性的方法叫做BOM. 3.駝峰式命名(myMood)是函數(shù)名、方法名和對(duì)象屬性名的命名首選格式。 4.命名變量...
摘要:但是,最好使用差異化的類型定義,函數(shù)簽名如下其實(shí)二者說(shuō)的是同一件事。后者的返回值和初始函數(shù)的返回值相同,即。破壞式更新和函數(shù)式更新的比較三的延遲計(jì)算的設(shè)計(jì)者們?cè)趯⒁霑r(shí)采取了比較特殊的方式。四匹配模式語(yǔ)言中暫時(shí)并未提供這一特性,略。 一、無(wú)處不在的函數(shù) 一等函數(shù):能夠像普通變量一樣使用的函數(shù)稱為一等函數(shù)(first-class function)通過(guò)::操作符,你可以創(chuàng)建一個(gè)方法引用,...
摘要:當(dāng)我們希望能界定這二者之間的區(qū)別時(shí),我們將第一種稱為純粹的函數(shù)式編程,后者稱為函數(shù)式編程。函數(shù)式編程我們的準(zhǔn)則是,被稱為函數(shù)式的函數(shù)或方法都只能修改本地變量。另一種觀點(diǎn)支持引用透明的函數(shù)式編程,認(rèn)為方法不應(yīng)該有對(duì)外部可見(jiàn)的對(duì)象修改。 一、實(shí)現(xiàn)和維護(hù)系統(tǒng) 1.共享的可變數(shù)據(jù) 如果一個(gè)方法既不修改它內(nèi)嵌類的狀態(tài),也不修改其他對(duì)象的狀態(tài),使用return返回所有的計(jì)算結(jié)果,那么我們稱其為純粹...
閱讀 2630·2023-04-26 01:44
閱讀 2676·2021-09-10 10:50
閱讀 1495·2019-08-30 15:56
閱讀 2439·2019-08-30 15:44
閱讀 573·2019-08-29 11:14
閱讀 3485·2019-08-26 11:56
閱讀 3083·2019-08-26 11:52
閱讀 987·2019-08-26 10:27