首頁 web前端 js教程 javascript函數式程式設計實例分析_javascript技巧

javascript函數式程式設計實例分析_javascript技巧

May 16, 2016 pm 04:02 PM
javascript 函數式程式設計

本文實例講述了javascript函數式程式設計。分享給大家供大家參考。具體分析如下:

js像其他動態語言一樣是可以寫高階函數的,所謂高階函數是可以操作函數的函數。因為在js中函數是一個徹底的對象,屬於第一類公民,這提供了函數式程式設計的先決條件。

下面給一個例子程式碼,出自一個js教程,功能是計算數組元素的平均值和標準差,先列出非函數式程式設計的一種寫法:

var data = [1,1,3,5,5];
var total = 0;
for(var i = 0;i < data.length;i++)
  total += data[i];
var mean = tatal/data.length; //平均数为3
//计算标准差
total = 0;
for(var i = 0;i < data.length;i++){
  var deviation = data[i] - mean;
  tatal += deviation * deviation;
  }
var stddev = Math,.sqrt(total/(data.length-1));//标准差为2
登入後複製

為了使用函數式編程,我們預先定義一些幫助函數(helper functions):

//将类数组对象转换为真正的数组
function array(a,n){
 return Array.prototype.slice.call(a,n||0);
}
//将函数实参传递至左侧
function partial_left(f){
 var args = arguments;
 return function(){
  var a = array(args,1);
  a = a.concat(array(arguments));
  return f.apply(this,a);
 };
}
//将函数的实参传递至右侧
function partial_right(f){
 var args = arguments;
 return function(){
  var a = array(arguments);
  a = a.concat(array(args,1));
  return f.apply(this,a);
 };
}
//该函数实参被用做模版,
//实参列表中的undefined值会被实际实参值填充。
function partial(f){
 var args = arguments;
 return function(){
  var a = array(args,1);
  var i = 0,j = 0;
  for(;i<a.length;i++)
   if(a[i] === undefined)
    a[i] = arguments[j++];
  a = a.concat(array(arguments,j));
  return f.apply(this,a);
 };
}
//返回一个函数类似于f(g())
function compose(f,g){
 return function(){
  return f.call(this,g.apply(this,arguments));
 };
}
登入後複製

下面我們給出完全用函數式程式設計的js程式碼:

var data = [1,1,3,5,5];
var sum = function(x,y){return x+y;};
var product = function(x,y){return x*y;};
var neg = partial(product,-1);
var square = partial(Math.pow,undefined,2);
var sqrt = partial(Math.pow,undefined,0.5);
var reciprocal = partial(Math.pow,undefined,-1);
//好吧,高潮来鸟 :)
var mean = product(reduce(data,sum),reciprocal(data.length));
var stddev = sqrt(product(reduce(map(data,compose(square,partial(sum,neg(mean)))),sum),reciprocal(sum(data.length,-1))));
登入後複製

除了reduce和map函數,其他函數前面都給了。 reduce函數類似與ruby中的inject函數:

ary = (1..10).to_a
ary.inject(0) {|sum,i|sum + i} //结果为55
登入後複製

js的寫法如下:

var ary = [1,2,3,4,5,6,7,8,9,10]
ary.reduce(function(sum,i){
 return sum + i;
},0);
登入後複製

0為sum的初始值,如果省略則sum為陣列第一個元素的值,這裡可以省略。

map函數也很簡單,類似與對數組的每一個元素做操作,然後返回一個經過操作後的數組,就以ruby代碼為例,js代碼與此類似:

a = (1..3).to_a; #数组[1,2,3]
a.map {|x| x*2} #返回新数组[2,4,6]
登入後複製

下面我們來分析下那一長串的程式碼:)

sum和product定義了元素相加和相乘的函數;

neg也是一個函數函數等價於:product(-1,x),即對x值求負;

square函數等價於:Math.pow(x,2),即計算x的平方值,注意這裡partial的第二個參數是undefined,這表示這裡的形參會被第一個實參填補;再說的明白點:square(x)功能等於Math.pow(x,2)。

sqrt函數和square類似,功能等價於:Math.pow(x,0.5),相當於計算x的開二次方。
最後一個函數reciprocal也沒什麼難度,等價於:Math.pow(x,-1),即計算x的負一次方,相當於計算x的倒數。

下面就是如何把上面各種函數揉捏在一起鳥 :)

先看平均值的計算,很簡單:就是先計算數組元素的和然後再乘以數組長度的倒數,即數組和/數組長度。

最後來看似乎很難的標準差,我們最好由內向外看:
先看包含neg的那一層:

//等价于函数sum(-1 * mean + x)
partial(sum,neg(mean)
登入後複製

下面看compose函數:

//下面在源代码上做了等价替换,可以再次等价于:
//square(sum(-1*mean + x)),再次展开(我剥,我剥,我剥洋葱...):
//Math.pow(sum(-1*mean + x),2);
compose(square,sum(-1*mean + x))
登入後複製

接下來看map函數:

//很清楚吧! ?即data中每一個元素都為一個x,將其傳入後面的函數,然後傳回一個計算的新數組,即新數組中的每個元素的值是data中的每個元素加上data負的平均數,然後對其結果計算2次方的結果。

map(data,Math.pow(sum(-1*mean + x),2))
登入後複製

再接著看map外面的reduce函數:

//将前面新数组的每个元素值加起来。
reduce(map(...),sum)
登入後複製

然後看一下reciprocal函數:

//等价于求(data.length-1)的倒数
reciprocal(sum(data.length,-1))
登入後複製

再看外層的product函數:

//等价于新数组元素的和除以(data.length-1)
product(reduce(...),reciprocal(...))
登入後複製

最外層的sqrt表示對以上除法得出的結果求平方根;大家可以對照一下前面非函數編程的代碼,是一樣一樣滴:) 看似蠻怕人的一大坨代碼,展開分析後難度立刻將至零。如果各位看官最後表示還是未看明白,那完全是本貓語言表達能力的問題,歡迎提問。

解釋完畢,打完收功,大功告成。

希望本文所述對大家的javascript程式設計有所幫助。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1421
52
Laravel 教程
1315
25
PHP教程
1266
29
C# 教程
1239
24
簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

如何在JavaScript中取得HTTP狀態碼的簡單方法 如何在JavaScript中取得HTTP狀態碼的簡單方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP狀態碼取得方法簡介:在進行前端開發中,我們常常需要處理與後端介面的交互,而HTTP狀態碼就是其中非常重要的一部分。了解並取得HTTP狀態碼有助於我們更好地處理介面傳回的資料。本文將介紹使用JavaScript取得HTTP狀態碼的方法,並提供具體程式碼範例。一、什麼是HTTP狀態碼HTTP狀態碼是指當瀏覽器向伺服器發起請求時,服務

如何利用懶惰求值優化Golang函數式程式? 如何利用懶惰求值優化Golang函數式程式? Apr 16, 2024 am 09:33 AM

透過使用惰性資料結構,可以在Go語言中實現惰惰求值:建立一個包裝器類型,封裝實際值,僅在需要時才計算。在函數式程式中最佳化斐波那契數列的計算,延後中間值的計算,直到實際需要。這可以消除不必要的開銷,提高函數式程式的效能。

用 C++ lambda 表達式實作函數式程式設計有什麼好處? 用 C++ lambda 表達式實作函數式程式設計有什麼好處? Apr 17, 2024 am 10:18 AM

C++lambda表達式為函數式程式設計帶來了優勢,包括:簡潔性:匿名內嵌函數,提升程式碼可讀性。程式碼重用:可傳遞或儲存lambda表達式,方便重複使用程式碼。封裝:提供封裝程式碼段的方法,無需建立單獨函數。實戰案例:過濾列表中的奇數。計算列表中元素的總和。 lambda表達式實現了函數式程式設計的簡潔性、可重複使用性和封裝性。

golang函數式程式設計的常見錯誤與陷阱 golang函數式程式設計的常見錯誤與陷阱 Apr 30, 2024 pm 12:36 PM

在Go中使用函數式程式設計時需要注意五個常見錯誤和陷阱:避免引用意外修改,確保傳回新建立的變數。解決並發性問題,使用同步機製或避免捕獲外部可變狀態。謹慎使用偏函數化,以提高程式碼可讀性和可維護性。始終處理函數中的錯誤,確保應用程式的健全性。考慮效能影響,使用內聯函數、扁平化資料結構和操作批次來最佳化程式碼。

Python Lambda表達式:縮寫,簡潔,強大 Python Lambda表達式:縮寫,簡潔,強大 Feb 19, 2024 pm 08:10 PM

pythonLambda表達式是一個強大且靈活的工具,可用於建立簡潔、可讀且易於使用的程式碼。它們非常適合快速建立匿名函數,這些函數可以作為參數傳遞給其他函數或儲存在變數中。 Lambda表達式的基本語法如下:lambdaarguments:expression例如,以下Lambda表達式將兩個數字相加:lambdax,y:x+y這個Lambda表達式可以傳遞給另一個函數作為參數,如下所示:defsum( x,y):returnx+yresult=sum(lambdax,y:x+y,1,2)在這個例子

Python Lambda表達式:揭秘匿名函數的強大奧秘 Python Lambda表達式:揭秘匿名函數的強大奧秘 Feb 24, 2024 am 09:01 AM

python中的Lambda表達式是匿名函數的另一種語法形式。它是一個小型匿名函數,可以在程式中任何地方定義。 Lambda表達式由一個參數列表和一個表達式組成,表達式可以是任何有效的Python表達式。 Lambda表達式的語法如下:lambdaargument_list:expression例如,下面的Lambda表達式傳回兩個數字的和:lambdax,y:x+y這個Lambda表達式可以傳遞給其他函數,例如map()函數:numbers=[ 1,2,3,4,5]result=map(lambda

C++ 函式的函數式程式設計特性有哪些? C++ 函式的函數式程式設計特性有哪些? Apr 11, 2024 pm 06:12 PM

C++支援函數式程式設計特性,包括:純函數:使用const修飾符聲明,不修改輸入或依賴外部狀態。不可變性:使用const關鍵字聲明變量,無法修改其值。惰性求值:使用std::lazy函數建立惰性值,延遲計算表達式。遞歸:函數呼叫自身的函數式程式設計技術,使用return自身呼叫。

See all articles