目錄
反柯里化
通用反柯里化函數
通用uncurrying 函數的進擊
首頁 web前端 js教程 JS中的反柯里化

JS中的反柯里化

Aug 19, 2017 am 10:33 AM
javascript

反柯里化

相反,反柯里化的作用在與擴大函數的適用性,使本來作為特定對象所擁有的功能的函數可以被任意對象所用.
即把如下給定的函數簽名,


obj.func(arg1, arg2)
登入後複製


轉換成函數形式,簽名如下:


func(obj, arg1, arg2)
登入後複製


這就是反柯里化的形式化描述。

例如,下面的一個簡單實作:


Function.prototype.uncurrying = function() {    var that = this;    return function() {        return Function.prototype.call.apply(that, arguments);
    }
};function sayHi () {    return "Hello " + this.value +" "+[].slice.call(arguments);
}var sayHiuncurrying=sayHi.uncurrying();
console.log(sayHiuncurrying({value:'world'},"hahaha"));
登入後複製


解釋:

  • #uncurrying是定義在Function的prototype上的方法,因此對所有的函數都可以使用此方法。呼叫時候:sayHiuncurrying=sayHi.uncurrying(),所以uncurrying中的this 指向的是sayHi 函數; (一般原型方法中的this 不是指向原型對象prototype,而是指向調用對象,在這裡調用對像是另一個函數,在javascript中函數也是物件)

  • call.apply(that, arguments) 把that 設定為call 方法的上下文,然後將arguments 傳給call方法,前文的例子,that 實際指向sayHi,所以呼叫sayHiuncurrying(arg1, arg2, ...) 相當於sayHi.call(arg1, arg2, ...);

  • sayHi. call(arg1, arg2, ...), call 函式把arg1 當做sayHi的上下文,然後把arg2,... 等剩下的參數傳給sayHi,因此最後相當於arg1.sayHi(arg2,...) ;

  • 因此,這相當於sayHiuncurrying(obj,args) 等於obj.sayHi(args)。

最後,我們反過來看,其實反柯里化相當於把原來sayHi(args) 的形式,轉換成了sayHiuncurrying(obj,args),使得sayHi的使用範圍泛化了。 更抽像地表達, uncurryinging反柯里化,使得原來 x.y(z) 調用,可以轉成 y(x',z) 形式的調用 。 假設x' 為x或其他對象,這就擴大了函數的使用範圍。

通用反柯里化函數

上面例子中把uncurrying寫進了prototype,這不太好,我們其實可以把uncurrying 單獨封裝成一個函數;


#
var uncurrying= function (fn) {    return function () {        var args=[].slice.call(arguments,1);        return fn.apply(arguments[0],args);        
    }    
};
登入後複製


上面這個函數很清楚直接。
使用時呼叫uncurrying 並傳入一個現有函數fn, 反柯里化函數會傳回一個新函數,該新函數接受的第一個實參將綁定為fn 中this的上下文,其他參數將傳遞給fn 作為參數。

所以,對反柯里化更通俗的解釋可以是 函數的借用,是函數能夠接受處理其他對象,透過借用泛化、擴大了函數的使用範圍。

所以 uncurrying更常見的用法是對 Javascript 內建的其他方法的 借調 而不用自己都去實作一遍。

文字描述比較繞,還是繼續看程式碼:


var test="a,b,c";
console.log(test.split(","));var split=uncurrying(String.prototype.split);   //[ 'a', 'b', 'c' ]console.log(split(test,','));                   //[ 'a', 'b', 'c' ]
登入後複製


split=uncurrying(String.prototype.split ) 給uncurrying 傳入一個具體的fn,即String.prototype.split ,split 函數就具有了String.prototype.split 的功能,函數呼叫split(test,',') 時,傳入的第一個參數為split 執行的上下文,剩下的參數相當於傳給原String.prototype.split 函數。

再看一個例子:


var $ = {};
console.log($.push);                          // undefinedvar pushUncurrying = uncurrying(Array.prototype.push);
$.push = function (obj) {
    pushUncurrying(this,obj);
};
$.push('first');
console.log($.length);                        // 1console.log($[0]);                            // firstconsole.log($.hasOwnProperty('length'));      // true
登入後複製


#這裡模仿了一個「類似jquery庫” 實作時藉用Array 的push 方法。 我們知道物件是沒有push 方法的,所以console.log(obj.push) 回傳undefined,可以藉用Array 來處理push,由原生的陣列方法(js引擎)來維護偽數組物件的length 屬性和陣列成員。

同樣的道理,我們還可以繼續有:


var indexof=uncurrying(Array.prototype.indexOf);
$.indexOf = function (obj) {    return indexof(this,obj);
};
$.push("second");
console.log($.indexOf('first'));              // 0console.log($.indexOf('second'));             // 1console.log($.indexOf('third'));              // -1
登入後複製


例如我們在實作自己的類別庫時,有些方法如果有些方法和原生的類似,那麼可以透過uncurrying 借用原生方法。

我們也可以把Function.prototype.call/apply 方法uncurring,例如:


var call= uncurrying(Function.prototype.call);var fn= function (str) {
    console.log(this.value+str);
};var obj={value:"Foo "};
call(fn, obj,"Bar!");                       // Foo Bar!
登入後複製


這樣可以非常靈活地把函數也當作一個普通「資料」來使用,有函數式程式的趕腳,在一些類別庫中常常能看到這樣的用法。

通用uncurrying 函數的進擊

上面的uncurrying 函數是比較符合思維習慣容易理解的版本,接下來一路進擊,看幾個其他版本:

首先,如果B格高一點,uncurrying 也可能寫成這樣:


var uncurrying= function (fn) {    return function () {        var context=[].shift.call(arguments);        return fn.apply(context,arguments);
    }
};
登入後複製


當然如果還需要再提升B格,那麼還可以是這樣:


var uncurrying= function (fn) {    return function () {        
        return Function.prototype.call.apply(fn,arguments);
    }
};
登入後複製

以上是JS中的反柯里化的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡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脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

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

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

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

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

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

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

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

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

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

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

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

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

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

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

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

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

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

See all articles