函數式JavaScript編程指南

來源:互聯網
上載者:User
簡介

你是否知道JavaScript其實也是一個函數式程式設計語言呢?本指南將教你如何利用JavaScript的函數式特性。

要求:你應當已經對JavaScript和DOM有了一個基本的瞭解。

寫這篇指南的目的是因為關於JavaScript編程的資料太多了但是極少的資料提到了JavaScript的函數式特性。在本指南中,我只會講解這些基本知識而不會深入其它的函數式語言或這是Lambda運算元。

你可以點擊所有的例子然後你所看到的代碼就會被執行,這樣就可以令指南變得具有互動性。

第一課 —— 匿名函數

我們將首先介紹匿名函數。一個匿名函數就是一個沒有名字的函數。
你可以認為他們是一次性函數。當你只需要用一次某個函數時,他們就特別有用。通過使用匿名函數,沒有必要把函數一直放在記憶體中,所以使用匿名函數更加有效率。

例Example:

下面兩個函數處理同樣的事情,而average在給z賦值結束之後一直保留——但匿名函數則不會。

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);

這很自然得引出了我們下面的一節課函數作為值

第二課 – 函數作為值

事實上,我們一般在JavaScript中聲明函數的方式可以看作是一個簡化了的文法(也就是文法糖syntactic sugar)。

例:

下面兩個運算式其實完全一樣。所以左邊的運算式僅僅是右邊的簡寫。

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) );

從這裡可以得出一個結論,函數是一個值就像字串、數字或數組一樣。這還出現幾個問題:

是否可以把函數作為參數傳遞?
可以,見下面的例子。
是否可以即時產生函數?
當然了,這是一個進階的主題,它可以通過eval函數來完成。

例:

這個例子示範了如何把函數作為參數傳遞。

var applyFun = function (f,x,y) { return f(x,y); };var add = function(x,y) {  return x+y;};alert( applyFun(add,3,4) ); // 7
第三課 – 兩種方式調用函數

在JavaScript中,有兩種調用函數的方式。一般的方式是把參數放在括弧中,如alert(42)。另一種方式是同時把函數和參數都放在括弧中,如(alert)(42)。

例:

alert(42);
(alert) (42);
(function(x) { alert(x-13); }) (55);

為什麼函數兩邊的括弧很重要:如果你寫了括弧,那麼在括弧中的代碼就會被先計算。在計算之後,括弧所在的地方就會有一個值。這個值可能是一個字串、一個數字或一個函數。

第四課 – “短路”條件調用

現在我們將學習如何使用“短路”條件調用。使用這個方法可以縮短原始碼同時代碼也變得更加可讀。

例:

這個文法並不是用在左運算式上,而是用在右運算式上。

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,現在我們已經學習了一些函數式JavaScript的內容。那麼它好在哪裡?函數式JavaScript編程之所以很重要有三條主要的理由:

  1. 有助於寫出模組化和可複用的代碼。
  2. 對事件處理常式非常有效。
  3. 很有趣!

在下面的篇幅中,我會給出更多關於前兩條理由的資訊

1. 模組化和可複用的代碼

現在你已經知道如何將函數作為值使用,那麼你也應該試試!一個很好的例子是數組內建的sort方法。預定義的sort()把所有的對象轉換成字串並把他們按照詞語的順序排序。但如果我們有使用者自訂的對象或者數字那麼它就不是很有用了。於是這個函數可以讓你給他一個進行比較的函數作為參數,如sort(compareFunction)。這個方法讓我們甚至不用接觸實際的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. 事件處理常式

對事件處理常式使用函數式編程也許是最直觀的函數作為值得應用了。既然這樣我們馬上就示範一個例子。

簡單的例子:;ie

現在有一個Button類,帶一個自訂的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"); });

Press me!

練習: 為什麼我們要把alert包裹在一個匿名函數中?

進階例子:

現在我們想改進我們的Button類。每一個按鈕都被分配了一個值當按鈕被點擊時顯示該值。首先我們調整我們的類:

function Button(value) {this.value = value;this.button = document.createElement("button");this.button.appendChild(document.createTextNode("test"));}

下面你也許要嘗試寫下面的代碼:

this.button.onclick = function() { alert(this.value); };

如果你執行它你就會發現提示框中間是空的。為什麼會這樣呢?其實原因在於JavaScript的可見度規則。當onclick函數被執行時this指向的是按鈕的DOM節點而非自訂的按鈕對象。

我們如何解決這個問題? 使用函數式編程:

this.button.onclick = (function(v) { return function() { alert(v); };}) (this.value);

這種情況下執行該匿名函數會將v綁定到this.value上。

 

轉自:http://shiningray.cn/functional_javascript_programming.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.