函數(shù)式JavaScript編程指南
你是否知道JavaScript其實(shí)也是一個(gè)函數(shù)式編程語(yǔ)言呢?本指南將教你如何利用JavaScript的函數(shù)式特性。
要求:你應(yīng)當(dāng)已經(jīng)對(duì)JavaScript和DOM有了一個(gè)基本的了解。
寫這篇指南的目的是因?yàn)殛P(guān)于JavaScript編程的資料太多了但是極少的資料提到了JavaScript的函數(shù)式特性。在本指南中,我只會(huì)講解這些基本知識(shí)而不會(huì)深入其它的函數(shù)式語(yǔ)言或這是Lambda算子。
你可以點(diǎn)擊所有的例子然后你所看到的代碼就會(huì)被執(zhí)行,這樣就可以令指南變得具有交互性。你也可以使用這個(gè)沙箱來(lái)嘗試。
第一課 —— 匿名函數(shù)
第二課 - 函數(shù)作為值
第三課 - 兩種方式調(diào)用函數(shù)
第四課 - “短路”條件調(diào)用
第五課 - 它好在哪里
JavaScript Programming 原文地址:http://www.pfeiffer-mediation.de/remast/javascript.php 翻譯:ShiningRay
函數(shù)式JavaScript編程指南
簡(jiǎn)介
你是否知道JavaScript其實(shí)也是一個(gè)函數(shù)式編程語(yǔ)言呢?本指南將教你如何利用JavaScript的函數(shù)式特性。
要求:你應(yīng)當(dāng)已經(jīng)對(duì)JavaScript和DOM有了一個(gè)基本的了解。
寫這篇指南的目的是因?yàn)殛P(guān)于JavaScript編程的資料太多了但是極少的資料提到了JavaScript的函數(shù)式特性。在本指南中,我只會(huì)講解這些基本知識(shí)而不會(huì)深入其它的函數(shù)式語(yǔ)言或這是Lambda算子。
你可以點(diǎn)擊所有的例子然后你所看到的代碼就會(huì)被執(zhí)行,這樣就可以令指南變得具有交互性。你也可以使用這個(gè)沙箱來(lái)嘗試。
第一課 —— 匿名函數(shù)
我們將首先介紹匿名函數(shù)。一個(gè)匿名函數(shù)就是一個(gè)沒(méi)有名字的函數(shù)。
你可以認(rèn)為他們是一次性函數(shù)。當(dāng)你只需要用一次某個(gè)函數(shù)式,他們就特別有用。通過(guò)使用匿名函數(shù),沒(méi)有必要把函數(shù)一直放在內(nèi)存中,所以使用匿名函數(shù)更加有效率。
例Example:
下面兩個(gè)函數(shù)處理同樣的事情,而 average在給z賦值結(jié)束之后一直保留——但匿名函數(shù)則不會(huì)。function average(x,y) { return (x+y)/2; } var z = average(1,3); alert(z);
var z = function(x,y) { return (x+y)/2; } (1,3); alert(z);
這很自然得引出了我們下面的一節(jié)課函數(shù)作為值。
第二課 - 函數(shù)作為值
事實(shí)上,我們一般在JavaScript中聲明函數(shù)的方式可以看作是一個(gè)簡(jiǎn)化了的語(yǔ)法(也就是語(yǔ)法糖,syntactic sugar)。
例:
下面兩個(gè)表達(dá)式其實(shí)完全一樣。所以左邊的表達(dá)式僅僅是右邊的簡(jiǎn)寫。function average(x,y) { return (x+y)/2; } alert( average(1,3) );
var average = function(x,y) { return (x+y)/2; } alert( average(1,3) );
從這里可以得出一個(gè)結(jié)論,函數(shù)是一個(gè)值就像字符串、數(shù)字或數(shù)組一樣。這還出現(xiàn)幾個(gè)問(wèn)題:
- 我是否可以把函數(shù)作為參數(shù)傳遞?
- 可以,見(jiàn)下面的例子。
- 是否可以實(shí)時(shí)生成函數(shù)?
- 當(dāng)然了,這是一個(gè)高級(jí)的主題,它可以通過(guò)eval函數(shù)來(lái)完成。小提示:看看本頁(yè)面的源代碼。
例:
這個(gè)例子演示了如何把函數(shù)作為參數(shù)傳遞。var applyFun = function (f,x,y) { return f(x,y); }; var add = function(x,y) { return x+y; }; alert( applyFun(add,3,4) ); // 7
第三課 - 兩種方式調(diào)用函數(shù)
在JavaScript中,有兩種調(diào)用函數(shù)的方式。一般的方式是把參數(shù)放在括號(hào)中,如alert(42)。另一種方式是同時(shí)把函數(shù)和參數(shù)都放在括號(hào)中,如(alert)(42)。
例:
alert(42);
(alert) (42);
(function(x) { alert(x-13); }) (55);
為什么函數(shù)兩邊的括號(hào)很重要: 如果你寫了括號(hào),那么在括號(hào)中的代碼就會(huì)被先計(jì)算。在計(jì)算之后,括號(hào)所在的地方就會(huì)有一個(gè)值。這個(gè)值可能是一個(gè)字符串、一個(gè)數(shù)字或一個(gè)函數(shù)。
第四課 - “短路”條件調(diào)用
現(xiàn)在我們將學(xué)習(xí)如何使用“短路”條件調(diào)用。使用這個(gè)方法可以縮短源代碼同時(shí)代碼也變得更加可讀。
例:
這個(gè)語(yǔ)法并不是用在左表達(dá)式上,而是用在右表達(dá)式上。var f = false; var t = true; var z; if(f) z = 4; else if(t) z = 2; alert(z);
var f = false; var t = true; var z = (f && 4) || (t && 2); alert(z);
第五課 - 它好在哪里
OK,現(xiàn)在我們已經(jīng)學(xué)習(xí)了一些函數(shù)式JavaScript的內(nèi)容。那么它好在哪里?函數(shù)式JavaScript編程之所以很重要有三條主要的理由:- 它有助于寫出模塊化和可服用的代碼。
- 它對(duì)事件處理程序非常有效。
- 它很有趣!
1. 模塊化和可復(fù)用的代碼
現(xiàn)在你已經(jīng)知道如何將函數(shù)作為值使用,那么你也應(yīng)該試試!一個(gè)很好的例子是數(shù)組內(nèi)建的sort方法。預(yù)定義的sort()把所有的對(duì)象轉(zhuǎn)換成字符串并把他們按照詞語(yǔ)的順序排序。但如果我們有用戶自定義的對(duì)象或者數(shù)字那么它就不是很有用了。于是這個(gè)函數(shù)可以讓你給他一個(gè)進(jìn)行比較的函數(shù)作為參數(shù),如sort(compareFunction)。這個(gè)方法讓我們甚至不用接觸實(shí)際的sort方法。
例:
var myarray = new Array(6,7,9,1,-1); var sortAsc = function(x,y) { return x-y; }; var sortDesc = function(x,y) { return y-x; }; myarray.sort(sortDesc); alert(myarray); myarray.sort(sortAsc); alert(myarray);
2. 事件處理程序
對(duì)事件處理程序使用函數(shù)式編程也許是最直觀的函數(shù)作為值得應(yīng)用了。既然這樣我們馬上就演示一個(gè)例子。
簡(jiǎn)單的例子:;ie
現(xiàn)在有一個(gè)Button類,帶一個(gè)自定義的onclick行為。function Button(clickFunction) { this.button = document.createElement("button"); this.button.appendChild(document.createTextNode("Press me!")); this.button.onclick = clickFunction; } var bt = new Button(function() { alert("42"); });
練習(xí): 為什么我們要把alert包裹在一個(gè)匿名函數(shù)中?
高級(jí)例子:
現(xiàn)在我們想改進(jìn)我們的Button類。每一個(gè)按鈕都被分配了一個(gè)值當(dāng)按鈕被點(diǎn)擊時(shí)顯示該值。首先我們調(diào)整我們的類:
function Button(value) { this.value = value; this.button = document.createElement("button"); this.button.appendChild(document.createTextNode("test")); }
下面你也許要嘗試寫下面的代碼:
this.button.onclick = function() { alert(this.value); };
如果你執(zhí)行它你就會(huì)發(fā)現(xiàn)提示框中間是空的。為什么會(huì)這樣呢?其實(shí)原因在于JavaScript的可見(jiàn)性規(guī)則。當(dāng)onclick函數(shù)被執(zhí)行時(shí)this指向的是按鈕的DOM節(jié)點(diǎn)而非自定義的按鈕對(duì)象。
我們?nèi)绾谓鉀Q這個(gè)問(wèn)題? 使用函數(shù)式編程:
this.button.onclick = (function(v) { return function() { alert(v); }; }) (this.value);
這種情況下執(zhí)行該匿名函數(shù)會(huì)將v綁定到this.value上。
沙箱
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁(yè)面才能執(zhí)行]
更多信息
下面是關(guān)于函數(shù)式JavaScript編程的一些有趣的鏈接:- w3future.com - 針對(duì)事件處理函數(shù)和回調(diào)函數(shù)的函數(shù)式編程
- svendtofte.com - 實(shí)用的(& 函數(shù)式的)JavaScript代碼片斷
- svendtofte.com - 極好的JavaScript庫(kù)(包括 map, fold, ...)
- CodingForums - 關(guān)于使用Lambda算子的函數(shù)式JavaScript的一篇更加理論性的文章
- Lambda tutorial - 關(guān)于在JavaScript中編碼Lambda算子的教程
- The Little JavaScripter - 關(guān)于 Scheme 和 JavaScript 之間的比較
展望
本節(jié)給大家展示一下JavaScript的未來(lái)。一個(gè)非常振奮人心的JavaScript特性——E4X,一個(gè)JavaScript中直接的XML支持。- Wikipedia on E4X - 關(guān)于 E4X 的很好的介紹
- Mozilla E4X - Brandon Eich (Mozilla首席架構(gòu)師)關(guān)于E4X的演示
相關(guān)文章
javascript 瀏覽器類型和版本號(hào)檢測(cè)代碼(兼容多瀏覽器)
果對(duì)javascript了解不是特別深入的話,很容易就會(huì)寫出不兼容的代碼(就像我),這時(shí)候就得判斷瀏覽器了。比如事件偵聽(tīng)、一些鼠標(biāo)和鍵盤事件、Range等,一些都會(huì)不一樣.下面列出幾種常用的檢測(cè)瀏覽器方法,以饗觀眾!2010-04-04一個(gè)檢測(cè)表單數(shù)據(jù)的JavaScript實(shí)例
這篇文章主要介紹了一個(gè)檢測(cè)表單數(shù)據(jù)的JavaScript實(shí)例,很簡(jiǎn)單,很實(shí)用,比較適合初學(xué)者2014-10-10基于JavaScript實(shí)現(xiàn)單選框下拉菜單添加文件效果
這篇文章主要介紹了基于JavaScript實(shí)現(xiàn)單選框下拉菜單添加文件效果的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06Javascript中匿名函數(shù)的調(diào)用與寫法實(shí)例詳解(多種)
js中定義函數(shù)的方式有很多種,函數(shù)直接量就是其中一種,下面通過(guò)本文給大家介紹匿名函數(shù)是如何調(diào)用的及匿名函數(shù)的n中寫法,對(duì)js匿名函數(shù)調(diào)用,js匿名函數(shù)寫法相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2016-01-01利用JS輕松實(shí)現(xiàn)獲取表單數(shù)據(jù)
本文主要介紹了利用JS輕松實(shí)現(xiàn)獲取表單數(shù)據(jù)。方法有別于原始的做法,大家可以試著找原始做法與本文所說(shuō)方法之間的區(qū)別。有興趣的朋友可以看下,希望對(duì)大家有所幫助2016-12-12