詳解JavaScript函數柯里化
詳解JavaScript函數柯里化
百度百科對柯里化的解釋:在電腦科學中,柯里化(Currying)是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,並且傳回接受餘下的參數且傳回結果的新函數的技術。這項技術由 Christopher Strachey 以邏輯學家 Haskell Curry 命名的,儘管它是 Moses Schnfinkel 和 Gottlob Frege 發明的。
相信沒有幾個人在看了上面這段解釋之後能立刻理解函數柯里化是什麼東西。通俗一點講,函數柯里化的主要目的就是為了減少函數傳參,同時將一些固定參數私有化。下面展示一段非常簡單計算圓面積的程式碼來說明函數柯里化的原理:
//circle函数,接受半径r和πfunction circle(r,p){ //计算半径为r的圆的面积 var area=p*r*r; return area; }/* * 通过函数柯里化来简化circle函数,只传入半径就能计算出面积 * 不管怎么样,π是不会变的,因此我们将他写死,不需要外部调用传入 */function curryCircle(r){ var p=3.14; var area=p*r*r; return area; }
也許你會覺得這段程式碼很二,但這就是函數柯里化的真實面。當然上面的程式碼只是一個非常小的例子,真實世界中的函數柯里化會比它兇惡一點,下面來討論一個更通用的例子。假設π不是唯一的(例如我們有三種π),我們計算圓面積公式當中的π會根據場景不同而變化,這時候我們就不能直接寫死,而需要根據不同環境來配置π:
//circle函数,接受半径r和π function circle(r,p){ //计算半径为r的圆的面积 var area=p*r*r; return area; } //针对circle函数的柯里化函数function curry(fn,p){ var finalMethod=function(r){ var result=fn(r,p); return result; } return finalMethod; } //我们有3种不同的πvar curryCircle1=curry(circle,1.14); var curryCircle2=curry(circle,2.14); var curryCircle3=curry(circle,3.14); //输出:4.56 8.56 12.56 console.log(curryCircle1(2),curryCircle2(2),curryCircle3(2));
可以看到,curry方法透過封裝最基礎的circle方法,同時保存設定好的p參數(π),並傳回一個finalMethod方法,這樣我們最終呼叫finalMethod時就只需要傳入參數r(半徑)就可以完成。借助函數柯里化,我們擁有了三種簡化的計算圓面積方法。上面所示的函數柯里化只能適用於圓面積的計算,這次我們寫一個更通用的柯里化函數:
function curry(fn){ //第一个参数是基础执行方法,slice切除 var args=Array.prototype.slice.call(arguments,1); //直接返回匿名函数 return function(){ //slice新参数以便能调用concat var innerArgs=Array.prototype.slice.call(arguments); //将配置的参数和新传入的参数合并 var finalArgs=args.concat(innerArgs); return fn.apply(null,finalArgs); }; }
curry()函數的主要工作就是將被傳回函數的參數進行排序。 Curry()的第一個參數是要進行柯里化的函數,其他參數是要傳入的值。為了取得第一個參數之後的所有參數,在arguments物件上呼叫了slice()方法,並傳入參數1表示被傳回的陣列包含從第二個參數開始的所有參數。然後args數組包含了來自外部函數的參數。在內部函數中,創建了innerArgs數組用來存放所有傳入的參數(又一次使用了slice())。有了存放來自外部函數和內部函數的參數數組後,就可以使用concat()方法將他們合併成finalArgs。最後使用apply()將結果傳遞給函數。這樣就實現了一個通用的函數柯里化。如果到這此還有餘力的讀者可以接著往下看,我們將要介紹jQuery中所使用的函數柯里化。
在針對某個方法進行柯里化時,我們甚至不用傳入fn來告訴柯里化來包裝我們的函數,我們可以透過原型直接將函數和柯里化綁定:
Function.prototype.curry=function(){ //利用原型的便利,我们可以直接通过this引用到方法 var fn=this; var args=Array.prototype.slice.call(arguments); return function(){ var arg=0; //循环校验先前传入的参数和新传入的参数是否有差别 for(var i=0;i<args.length && arg<arguments.length;i++){ if(args[i]===undefined){ args[i]=arguments[arg++]; } } return fn.apply(this,args); }; };
與之前不同,我們透過this引用獲取了方法引用,這樣當我們需要將某個函數柯里化時,只要這樣寫就可以:
var delay=setTimeout.curry(undefined,10);
delay就是一個已經被提前設定了10毫秒延遲的setTimeout函數。我們仍然透過args來保存參數配置,不過這次有點差別:在for迴圈內部會校驗args和arguments的差別,以此判斷來完成參數拼接。所以傳給curry的參數必須是完整參數(即意味著不傳的值要傳入undefined)。最後我們實作了一個不需要傳入fn的柯里化方法。
詳解JavaScript函數柯里化
百度百科對柯里化的解釋:在電腦科學中,柯里化(Currying)是把接受多個參數的函數轉換成接受一個單一參數(原函數的第一個參數)的函數,並且傳回接受餘下的參數且傳回結果的新函數的技術。這項技術由 Christopher Strachey 以邏輯學家 Haskell Curry 命名的,儘管它是 Moses Schnfinkel 和 Gottlob Frege 發明的。
相信沒有幾個人在看了上面這段解釋之後能立刻理解函數柯里化是什麼東西。通俗一點講,函數柯里化的主要目的就是為了減少函數傳參,同時將一些固定參數私有化。下面展示一段非常簡單計算圓面積的程式碼來說明函數柯里化的原理:
//circle函数,接受半径r和πfunction circle(r,p){ //计算半径为r的圆的面积 var area=p*r*r; return area; }/* * 通过函数柯里化来简化circle函数,只传入半径就能计算出面积 * 不管怎么样,π是不会变的,因此我们将他写死,不需要外部调用传入 */function curryCircle(r){ var p=3.14; var area=p*r*r; return area; }
也許你會覺得這段程式碼很二,但這就是函數柯里化的真實面。當然上面的程式碼只是一個非常小的例子,真實世界中的函數柯里化會比它兇惡一點,下面來討論一個更通用的例子。假設π不是唯一的(例如我們有三種π),我們計算圓面積公式當中的π會根據場景不同而變化,這時候我們就不能直接寫死,而需要根據不同環境來配置π:
//circle函数,接受半径r和πfunction circle(r,p){ //计算半径为r的圆的面积 var area=p*r*r; return area; }//针对circle函数的柯里化函数function curry(fn,p){ var finalMethod=function(r){ var result=fn(r,p); return result; } return finalMethod; } //我们有3种不同的π var curryCircle1=curry(circle,1.14); var curryCircle2=curry(circle,2.14); var curryCircle3=curry(circle,3.14); //输出:4.56 8.56 12.56 console.log(curryCircle1(2),curryCircle2(2),curryCircle3(2));
可以看到,curry方法通过封装最基础的circle方法,同时保存设置好的p参数(π),并返回一个finalMethod方法,这样我们最终调用finalMethod时就只需要传入参数r(半径)就可以完成。借助函数柯里化,我们拥有了三个简化的计算圆面积方法。上面展示的函数柯里化只能适用于圆面积的计算,这次我们编写一个更通用的柯里化函数:
function curry(fn){ //第一个参数是基础执行方法,slice切除 var args=Array.prototype.slice.call(arguments,1); //直接返回匿名函数 return function(){ //slice新参数以便能调用concat var innerArgs=Array.prototype.slice.call(arguments); //将配置的参数和新传入的参数合并 var finalArgs=args.concat(innerArgs); return fn.apply(null,finalArgs); }; }
curry()函数的主要工作就是将被返回函数的参数进行排序。Curry()的第一个参数是要进行柯里化的函数,其他参数是要传入的值。为了获取第一个参数之后的所有参数,在arguments对象上调用了slice()方法,并传入参数1表示被返回的数组包含从第二个参数开始的所有参数。然后args数组包含了来自外部函数的参数。在内部函数中,创建了innerArgs数组用来存放所有传入的参数(又一次使用了slice())。有了存放来自外部函数和内部函数的参数数组后,就可以使用concat()方法将他们合并成finalArgs。最后使用apply()将结果传递给该函数。这样就实现了一个通用的函数柯里化。如果到这此还有余力的读者可以接着往下看,我们将要介绍jQuery中使用的函数柯里化。
在针对某个方法进行柯里化时,我们甚至不用传入fn来告诉柯里化来包装我们的函数,我们可以通过原型直接将函数和柯里化绑定:
Function.prototype.curry=function(){ //利用原型的便利,我们可以直接通过this引用到方法 var fn=this; var args=Array.prototype.slice.call(arguments); return function(){ var arg=0; //循环校验先前传入的参数和新传入的参数是否有差别 for(var i=0;i<args.length && arg<arguments.length;i++){ if(args[i]===undefined){ args[i]=arguments[arg++]; } } return fn.apply(this,args); }; };
与之前不同,我们通过this引用获取了方法引用,这样当我们需要将某个函数柯里化时,只要这样写就可以:
var delay=setTimeout.curry(undefined,10);
delay就是一个已经被提前设定了10毫秒延迟的setTimeout函数。我们仍然通过args来保存参数配置,不过这次有点区别:在for循环内部会校验args和arguments的区别,以此判断来完成参数拼接。所以传给curry的参数必须是完整参数(即意味着不传的值要传入undefined)。最终我们实现了一个不需要传入fn的柯里化方法。
以上就是详解JavaScript函数柯里化 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

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

熱門話題

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

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

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