最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

用函數式編程技術編寫優(yōu)美的 JavaScript

 更新時間:2006年11月25日 00:00:00   作者:  

級別: 初級

Shantanu Bhattacharya (shantanu@justawordaway.com), 首席顧問, Siemens Information Systems Limited

2006 年 7 月 20 日

函數式或聲明性編程是非常強大的編程方法,正逐漸在軟件行業(yè)流行起來。這篇文章將介紹一些相關的函數式編程概念,并提供有效使用這些概念的示例。作者將解釋如何使用 JavaScript(TM)(JavaScript 能導入函數式編程的構造和特性)編寫優(yōu)美的代碼。

簡介

函數式編程語言在學術領域已經存在相當長一段時間了,但是從歷史上看,它們沒有豐富的工具和庫可供使用。隨著 .NET 平臺上的 Haskell 的出現,函數式編程變得更加流行。一些傳統(tǒng)的編程語言,例如 C++ 和 JavaScript,引入了由函數式編程提供的一些構造和特性。在許多情況下,JavaScript 的重復代碼導致了一些拙劣的編碼。如果使用函數式編程,就可以避免這些問題。此外,可以利用函數式編程風格編寫更加優(yōu)美的回調。

函數式編程

函數式編程只描述在程序輸入上執(zhí)行的操作,不必使用臨時變量保存中間結果。重點是捕捉 “是什么以及為什么”,而不是 “如何做”。與將重點放在執(zhí)行連續(xù)命令上的過程性編程相比,函數式編程的重點是函數的定義而不是狀態(tài)機(state machine)的實現。

大型知識管理系統(tǒng)應用程序從使用函數式編程風格上受益頗多,因為函數式編程簡化了開發(fā)。

因為函數式編程采用了完全不同的組織程序的方式,所以那些習慣于采用命令式范例的程序員可能會發(fā)現函數式編程有點難學。在這篇文章中,您將了解一些關于如何采用函數式風格,用 JavaScript 編寫良好的、優(yōu)美的代碼的示例。我將討論:

  • 函數式編程概念,包括匿名函數、調用函數的不同方法,以及將函數作為參數傳遞給其他函數的方式。

  • 函數式概念的運用,采用的示例包括:擴展數組排序;動態(tài) HTML 生成的優(yōu)美代碼;系列函數的應用。


函數式編程概念

請告訴每個人。請把這個提交給:

digg Digg
slashdot Slashdot

在那些通過描述 “如何做” 指定解決問題的方法的語言中,許多開發(fā)人員都知道如何進行編碼。例如,要編寫一個計算階乘的函數,我可以編寫一個循環(huán)來描述程序,或者使用遞歸來查找所有數字的乘積。在這兩種情況下,計算的過程都在程序中進行了詳細說明。清單 1 顯示了一個計算階乘的可能使用的 C 代碼。


清單 1. 過程風格的階乘
			
int factorial (int n)
{
 if (n <= 0)
  return 1;
 else
  return n * factorial (n-1);
}

這類語言也叫做過程性 編程語言,因為它們定義了解決問題的過程。函數式編程與這個原理有顯著不同。在函數式編程中,需要描述問題 “是什么”。 函數式編程語言又叫做聲明性 語言。同樣的計算階乘的程序可以寫成所有到 n 的數字的乘積。計算階乘的典型函數式程序看起來如 清單 2 中的示例所示。


清單 2. 函數式風格的階乘
				
factorial n, where n <= 0 	:= 1
factorial n  := foldr * 1 take n [1..]

第二個語句指明要得到從 1 開始的前 n 個數字的列表(take n [1..]),然后找出它們的乘積,1 為基元。這個定義與前面的示例不同,沒有循環(huán)或遞歸。它就像階乘函數的算術定義。一旦了解了庫函數(takefoldr)和標記(list notation [ ])的意義,編寫代碼就很容易,而且可讀性也很好。

只用三行 Miranda 代碼就可以編寫例程,根據參數,使用廣度優(yōu)先或深度優(yōu)先遍歷處理 n 叉樹的每個節(jié)點,而且元素可以是任何通用類型。

從歷史上看,函數式編程語言不太流行有各種原因。但是最近,有些函數式編程語言正在進入計算機行業(yè)。其中一個例子就是 .NET 平臺上的 Haskell。其他情況下,現有的一些語言借用了函數式編程語言中的一些概念。一些 C++ 實現中的迭代器和 continuation,以及 JavaScript 中提供的一些函數式構造(functional construct),就是這種借用的示例。但是,通過借用函數式構造,總的語言編程范例并沒有發(fā)生變化。JavaScript 并沒因為函數式構造的添加就變成了函數式編程語言。

我現在要討論 JavaScript 中的函數式構造的各種美妙之處,以及在日常編碼和工作中使用它們的方式。我們將從一些基本功能開始,然后用它們查看一些更有趣的應用。

匿名函數

在 JavaScript 中,可以編寫匿名函數或沒有名稱的函數。為什么需要這樣的函數?請繼續(xù)往下讀,但首先我們將學習如何編寫這樣一個函數。如果擁有以下 JavaScript 函數:
清單 3. 典型的函數

				
function sum(x,y,z) {
 return (x+y+z);
}

然后對應的匿名函數看起來應當如下所示:
清單 4. 匿名函數

				
function(x,y,z) {
 return (x+y+z);
}

要使用它,則需要編寫以下代碼:


清單 5. 應用匿名函數
				
var sum = function(x,y,z) {
 return (x+y+z);
}(1,2,3);
alert(sum);

使用函數作為值

也可以將函數作為值使用。還可以擁有一些所賦值是函數的變量。在最后一個示例中,還可以執(zhí)行以下操作:
清單 6. 使用函數賦值

				
var sum = function(x,y,z) {
 return (x+y+z);
}
alert(sum(1,2,3));

在上面 清單 6 的示例中,為變量 sum 賦的值是函數定義本身。這樣,sum 就成了一個函數,可以在任何地方調用。

調用函數的不同方法

JavaScript 允許用兩種方式調用函數,如清單 78 所示。


清單 7. 典型的函數應用
				
alert (“Hello, World!");


清單 8. 用函數作為表達式
				
(alert) (“Hello, World!");

所以也可以編寫以下代碼:


清單 9. 定義函數之后就可以立即使用它
( function(x,y,z) { return (x+y+z) } ) (1, 2, 3);

可以在括號中編寫函數表達式,然后傳遞給參數,對參數進行運算。雖然在 清單 8 的示例中,有直接包含在括號中的函數名稱,但是按 清單 9 中所示方式使用它時,就不是這樣了。

將函數作為參數傳遞給其他函數

也可以將函數作為參數傳遞給其他函數。雖然這不是什么新概念,但是在后續(xù)的示例中大量的使用了這個概念??梢詡鬟f函數參數,如 清單 10 所示。


清單 10. 將函數作為參數傳遞,并應用該函數
				
var passFunAndApply = function (fn,x,y,z) { return fn(x,y,z); };

var sum = function(x,y,z) {
 return x+y+z;
};

alert( passFunAndApply(sum,3,4,5) ); // 12

執(zhí)行最后一個 alert 語句輸出了一個大小為 12 的值。

使用函數式概念

前一節(jié)介紹了一些使用函數式風格的編程概念。所給的示例并沒有包含所有的概念,它們在重要性方面也沒有先后順序,只是一些與這個討論有關的概念而已。下面對 JavaScript 中的函數式風格作一快速總結:

  • 函數并不總是需要名稱。
  • 函數可以像其他值一樣分配給變量。
  • 函數表達式可以編寫并放在括號中,留待以后應用。
  • 函數可以作為參數傳遞給其他函數。

這一節(jié)將介紹一些有效使用這些概念編寫優(yōu)美的 JavaScript 代碼的示例。(使用 JavaScript 函數式風格,可以做許多超出這個討論范圍的事。)

擴展數組排序
先來編寫一個排序方法,可以根據數組元素的日期對數據進行排序。用 JavaScript 編寫這個方法非常簡單。數據對象的排序方法接受一個可選參數,這個可選參數就是比較函數。在這里,需要使用 清單 11 中的比較函數。


清單 11. 比較函數

function (x,y) {
	return x.date – y.date;
}

要得到需要的函數,請使用 清單 12 的示例。


清單 12. 排序函數的擴展
arr.sort( function (x,y) {	return x.date – y.date; } );

其中 arr 是類型數組對象。排序函數會根據 arr 數組中對象的日期對所有對象進行排序。比較函數和它的定義一起被傳遞給排序函數,以完成排序操作。使用這個函數:

  • 每個 JavaScript 對象都有一個 date 屬性。
  • JavaScript 的數組類型的排序函數接受可選參數,可選參數是用來排序的比較函數。這與 C 庫中的 qsort 函數類似。

動態(tài)生成 HTML 的優(yōu)美代碼
在這個示例中,將看到如何編寫優(yōu)美的代碼,從數組動態(tài)地生成 HTML??梢愿鶕臄祿械玫降闹瞪杀砀?。或者,也可以用數組的內容生成排序和未排序的列表。也可以生成垂直或水平的菜單項目。

清單 13 中的代碼風格通常被用來從數組生成動態(tài) HTML。


清單 13. 生成動態(tài) HTML 的普通代碼
var str=' ';
for (var i=0;i<arr.length;i++) {
 var element=arr[i];
 str+=... HTML generation code...
}
document.write(str);

可以用 清單 14 的代碼替換這個代碼。


清單 14. 生成動態(tài) HTML 的通用方式
						
Array.prototype.fold=function(templateFn) {
 var len=this.length;
 var str=' ';
 for (var i=0 ; i<len ; i++) 
	str+=templateFn(this[i]);
 return str;
}

function templateInstance(element) {
 return ... HTML generation code ...
}

document.write(arr.fold(templateInstance));

我使用 Array 類型的 prototype 屬性定義新函數 fold?,F在可以在后面定義的任何數組中使用該函數。

系列函數的應用
考慮以下這種情況:想用一組函數作為回調函數。為實現這一目的,將使用 window.setTimeout 函數,該函數有兩個參數。第一個參數是在第二個參數表示的毫秒數之后被調用的函數。清單 15 顯示了完成此操作的一種方法。
清單 15. 在回調中調用一組函數
window.setTimeout(function(){alert(‘First!');alert(‘Second!');}, 5000);

清單 16 顯示了完成此操作的更好的方式。


清單 16. 調用系列函數的更好的方式
Function.prototype.sequence=function(g) {
 var f=this;
 return function() {
  f();g();
 }
};
function alertFrst() { alert(‘First!'); }
function alertSec() { alert(‘Second!'); }
setTimeout( alertFrst.sequence(alertSec), 5000);

在處理事件時,如果想在調用完一個回調之后再調用一個回調,也可以使用 清單 16 中的代碼擴展。這可能是一個需要您自行完成的一個練習,現在您的興趣被點燃了吧。

相關文章

  • 一個JavaScript去除字符串末尾的空白實例代碼

    一個JavaScript去除字符串末尾的空白實例代碼

    這是一個JavaScript去除字符串末尾的空白實例代碼,很簡單,但很實用,喜歡的朋友可以參考下
    2014-09-09
  • 使用onbeforeunload屬性后的副作用

    使用onbeforeunload屬性后的副作用

    使用onbeforeunload屬性后的副作用...
    2007-03-03
  • 移動端腳本框架Hammer.js

    移動端腳本框架Hammer.js

    這篇文章主要為大家詳細介紹了一款開源的移動端腳本框架Hammer.js,可以完美的實現在移端開發(fā)的大多數事件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Javascript訪問html頁面的控件的方法詳細分析

    Javascript訪問html頁面的控件的方法詳細分析

    這段時間在公司比較的空閑,決定研究研究javascript訪問html控件,這是很普遍的,這里我系統(tǒng)的研究javascript的訪問方式,測試通過并有下面一些研究成就,供大家分享和補充。
    2008-08-08
  • setTimeout時間設置為0詳細解析

    setTimeout時間設置為0詳細解析

    setTimeout( ) 是屬于 window 的 method, 但我們都是略去 window 這頂層容器名稱, 這是用來設定一個時間, 時間到了, 就會執(zhí)行一個指定的 method,下面這篇文章主要給大家介紹了關于setTimeout時間設置為0的相關資料,需要的朋友可以參考下。
    2018-03-03
  • js?html5獲取input焦點的輸入框并賦值實例

    js?html5獲取input焦點的輸入框并賦值實例

    這篇文章主要為大家介紹了js?html5獲取input焦點的輸入框并賦值實現示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • js字符編碼函數區(qū)別分析

    js字符編碼函數區(qū)別分析

    js對文字編碼有3個函數: escape,encodeURI,encodeURIComponent, 對應的解碼函數:unescape,decodeURI,decodeURIComponent
    2008-06-06
  • 使用TypeScript在接口中定義靜態(tài)方法詳解

    使用TypeScript在接口中定義靜態(tài)方法詳解

    當我們談論面向對象編程時,最難理解的事情之一就是靜態(tài)屬性與實例屬性的概念,尤其是當我們試圖在靜態(tài)類型的基礎上進行動態(tài)語言類型化時,在本文中,我將主要介紹一下如何使用TypeScript在接口中定義靜態(tài)方法,需要的朋友可以參考下
    2023-10-10
  • js實現的訂閱發(fā)布者模式簡單示例

    js實現的訂閱發(fā)布者模式簡單示例

    這篇文章主要介紹了js實現的訂閱發(fā)布者模式,結合完整示例形式分析了js訂閱發(fā)布者模式相關實現與使用方法,需要的朋友可以參考下
    2020-03-03
  • js中數組排序sort方法的原理分析

    js中數組排序sort方法的原理分析

    這篇文章主要介紹了js中數組排序sort方法的原理,以實例形式分析了sort排序方法的運行機制,具有一定的參考借鑒價值,需要的朋友可以參考下
    2014-11-11

最新評論

青阳县| 灵山县| 区。| 永康市| 赤峰市| 平南县| 天气| 新田县| 太湖县| 永年县| 纳雍县| 元氏县| 广东省| 枣强县| 通辽市| 佛教| 当雄县| 刚察县| 兴化市| 桐乡市| 浙江省| 盘山县| 屏东市| 安庆市| 汤阴县| 安龙县| 蕉岭县| 南川市| 安远县| 罗田县| 达孜县| 永安市| 金秀| 沧州市| 万山特区| 库车县| 莎车县| 临沂市| 福安市| 通江县| 永定县|