JavaScript 中的函數(shù)式編程實(shí)踐
起源
- 函數(shù)式編程思想的源頭可以追溯到 20 世紀(jì) 30 年代奸绷,數(shù)學(xué)家阿隆左 . 丘奇在進(jìn)行一項(xiàng)關(guān)于問題的可計(jì)算性的研究层玲,也就是后來的 lambda 演算。
lambda 演算的本質(zhì)為 一切皆函數(shù)畔派,函數(shù)可以作為另外一個函數(shù)的輸出或者 / 和輸入润绵,一系列的函數(shù)使用最終會形成一個表達(dá)式鏈,這個表達(dá)式鏈可以最終求得一個值尘盼,而這個過程卿捎,即為計(jì)算的本質(zhì)。 - 然而午阵,這種思想在當(dāng)時的硬件基礎(chǔ)上很難實(shí)現(xiàn)底桂,歷史最終選擇了同丘奇的 lambda 理論平行的另一種數(shù)學(xué)理論:圖靈機(jī)作為計(jì)算理論,而采取另一位科學(xué)家馮 . 諾依曼的計(jì)算機(jī)結(jié)構(gòu)籽懦,并最終被實(shí)現(xiàn)為硬件。由于第一臺計(jì)算機(jī)即為馮 . 諾依曼的程序存儲結(jié)構(gòu)览濒,因此運(yùn)行在此平臺的程序也繼承了這種基因拖云,程序設(shè)計(jì)語言如 C/Pascal 等都在一定程度上依賴于此體系。
- 到了 20 世紀(jì) 50 年代乏苦,一位 MIT 的教授 John McCarthy 在馮 . 諾依曼體系的機(jī)器上成功的實(shí)現(xiàn)了 lambda 理論,取名為 LISP(LISt Processor), 至此函數(shù)式編程語言便開始活躍于計(jì)算機(jī)科學(xué)領(lǐng)域洞就。
概念
- 匿名函數(shù)
-
柯里化
柯里化是把接受多個參數(shù)的函數(shù)變換成接受一個單一參數(shù)(最初函數(shù)的第一個參數(shù))的函數(shù)掀淘,并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)的技術(shù)。這句話有點(diǎn)繞口倾贰,我們可以通過例子來幫助理解:
清單 2. 柯里化函數(shù)
function adder(num){
return function (x){return num + x; }
}
var add5 = adder(5);
var add6 = adder(6);
print(add5(1));
print(add6(1));
結(jié)果為:6 7
柯里化在 DOM 的回調(diào)中非常有用
-
高階函數(shù)
高階函數(shù)即為對函數(shù)的進(jìn)一步抽象
JavaScript 中的函數(shù)式編程
- 函數(shù)式編程風(fēng)格
在 JavaScript 中拦惋,函數(shù)本身為一種特殊對象,屬于頂層對象首尼,不依賴于任何其他的對象而存在言秸,因此可以將函數(shù)作為傳出 / 傳入?yún)?shù),可以存儲在變量中,以及一切其他對象可以做的事情 ( 因?yàn)楹瘮?shù)就是對象 )俱恶。 - 閉包及其使用
閉包是一個很有趣的主題范舀,當(dāng)在一個函數(shù) outter 內(nèi)部定義另一個函數(shù) inner,而 inner 又引用了 outter 作用域內(nèi)的變量锭环,在 outter 之外使用 inner 函數(shù)辅辩,則形成了閉包。描述起來雖然比較復(fù)雜玫锋,在實(shí)際編程中卻經(jīng)常無意的使用了閉包特性撩鹿。
清單 8. 一個閉包的例子
function outter(){
var n = 0;
return function (){ return n++;}
}
var o1 = outter();
o1();//n == 0
o1();//n == 1
o1();//n == 2
var o2 = outter();
o2();//n == 0
o2();//n == 1
匿名函數(shù) function(){return n++;} 中包含對 outter 的局部變量 n 的引用,因此當(dāng) outter 返回時键思,n 的值被保留 ( 不會被垃圾回收機(jī)制回收 ),持續(xù)調(diào)用 o1()吼鳞,將會改變 n 的值。而 o2 的值并不會隨著 o1() 被調(diào)用而改變失乾,第一次調(diào)用 o2 會得到 n==0 的結(jié)果纬乍,用面向?qū)ο蟮男g(shù)語來說,就是 o1 和 o2 為不同的 實(shí)例纽竣,互不干涉茧泪。
總的來說,閉包很簡單穴吹,不是嗎嗜侮?但是,閉包可以帶來很多好處顷霹,比如我們在 Web 開發(fā)中經(jīng)常用到的:
清單 9. jQuery 中的閉包
var con = $("div#con");
setTimeout( function (){ con.css({background:"gray"}); }, 2000);
上邊的代碼使用了 jQuery 的選擇器击吱,找到 id 為 con 的 div 元素,注冊計(jì)時器朵纷,當(dāng)兩秒中之后永脓,將該 div 的背景色設(shè)置為灰色。這個代碼片段的神奇之處在于革屠,在調(diào)用了 setTimeout 函數(shù)之后,con 依舊被保持在函數(shù)內(nèi)部似芝,當(dāng)兩秒鐘之后党瓮,id 為 con 的 div 元素的背景色確實(shí)得到了改變。應(yīng)該注意的是寞奸,setTimeout 在調(diào)用之后已經(jīng)返回了枪萄,但是 con 沒有被釋放,這是因?yàn)?con 引用了全局作用域里的變量 con瓷翻。
實(shí)際應(yīng)用中的例子
jQuery 是一個非常優(yōu)秀 JavaScript/Ajax 框架齐帚,小巧,靈活对妄,具有插件機(jī)制,事實(shí)上摩瞎,jQuery 的插件非常豐富琅豆,從表達(dá)驗(yàn)證篓吁,客戶端圖像處理杖剪,UI,動畫等等盛嘿。而 jQuery 最大的特點(diǎn)正如其宣稱的那樣次兆,改變了人們編寫 JavaScript 代碼的風(fēng)格。
作者參考資料
jQuery官方網(wǎng)站的地址,可以下載到最新的 jQuery 庫恃慧。
JavaScript 中的閉包:一篇優(yōu)秀的關(guān)于 JavaScript 閉包的論述渺蒿。
文中提到的 LISP 之根源的譯文,該文詳細(xì)的描述了 LISP 的其中基本原語茂装,很好的解釋了 LISP 的 可編程性。
函數(shù)式編程的基本概念:一篇關(guān)于 JavaScript 函數(shù)式編程的基本概念的文章城侧。
“JavaScript 框架比較”:在本文中况增,您將了解如何通過 JavaScript 框架更輕松、更快速地創(chuàng)建具有高度交互性和響應(yīng)性的 Web 站點(diǎn)和 Web 應(yīng)用程序歧强。
“JavaScript 開發(fā)工具包 ”:本專題為您收集了一些和目前業(yè)界比較流行的 JavaScript 開發(fā)工具包相關(guān)的資源为肮,從初級的入門介紹到高級的使用以及和其他開發(fā)語言、軟件集成的內(nèi)容茅特。
developerWorks 技術(shù)活動和網(wǎng)絡(luò)廣播:隨時關(guān)注 developerWorks 技術(shù)活動和網(wǎng)絡(luò)廣播棋枕。
developerWorks Web development 專區(qū):通過專門關(guān)于 Web 技術(shù)的文章和教程重斑,擴(kuò)展您在網(wǎng)站開發(fā)方面的技能。
developerWorks Ajax 資源中心:這是有關(guān) Ajax 編程模型信息的一站式中心窥浪,包括很多文檔漾脂、教程、論壇笨鸡、blog、wiki 和新聞形耗。任何 Ajax 的新信息都能在這里找到。
developerWorks Web 2.0 資源中心泰讽,這是有關(guān) Web 2.0 相關(guān)信息的一站式中心昔期,包括大量 Web 2.0 技術(shù)文章硼一、教程、下載和相關(guān)技術(shù)資源般贼。您還可以通過 Web 2.0 新手入門 欄目哼蛆,迅速了解 Web 2.0 的相關(guān)概念。