溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript函數(shù)柯里化有什么用

發(fā)布時(shí)間:2022-03-22 09:25:20 來(lái)源:億速云 閱讀:356 作者:小新 欄目:開(kāi)發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)JavaScript函數(shù)柯里化有什么用,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

函數(shù)柯里化

與函數(shù)綁定緊密相關(guān)的主題是函數(shù)柯里化(function currying),它用于創(chuàng)建已經(jīng)設(shè)置好了一個(gè)或多個(gè)參數(shù)的函數(shù)。函數(shù)柯里化的基本方法和函數(shù)綁定是一樣的:使用一個(gè)閉包返回一個(gè)函數(shù)。兩者的區(qū)別在于,當(dāng)函數(shù)被調(diào)用時(shí),返回的函數(shù)還需要設(shè)置一些傳入的參數(shù)。

function add(num1, num2) {
    return num1 + num2;
}
function curriedAdd(num2) {
    return add(5, num2);
}
console.log(add(2, 3)); //5
console.log(curriedAdd(3));//8

這段代碼定義了兩個(gè)函數(shù):add()和curriedAdd()。后者本質(zhì)上是在任何情況下第一個(gè)參數(shù)為5的add()版本。盡管從技術(shù)來(lái)說(shuō)curriedAdd()并非柯里化的函數(shù),但它很好地展示了其概念。

柯里化函數(shù)通常由以下步驟動(dòng)態(tài)創(chuàng)建:調(diào)用另一個(gè)函數(shù)并為它傳入要柯里化的函數(shù)和必要參數(shù)。

下面是創(chuàng)建柯里化函數(shù)的通用方式:

function curry(fn) {
    var args = Array.prototype.slice.call(arguments, 1);
    return function() {
        var innerArgs = Array.prototype.slice.call(arguments),
        finalArgs = args.concat(innerArgs);
        return fn.apply(null, finalArgs);
    };
}

curry()函數(shù)的主要工作就是將被返回函數(shù)的參數(shù)進(jìn)行排序。curry()的第一個(gè)參數(shù)是要進(jìn)行柯里化的函數(shù),其他參數(shù)是要傳入的值。

為了獲取第一個(gè)參數(shù)之后的所有參數(shù),在arguments對(duì)象上調(diào)用了slice()方法,并傳入?yún)?shù)1表示被返回的數(shù)組包含從第二個(gè)參數(shù)開(kāi)始的所有參數(shù)。然后args數(shù)組包含了來(lái)自外部函數(shù)的參數(shù)。在內(nèi)部函數(shù)中,創(chuàng)建了innerArgs數(shù)組用來(lái)存放所有傳入的參數(shù)(又一次用到了slice())。

有了存放來(lái)自外部函數(shù)和內(nèi)部函數(shù)的參數(shù)數(shù)組后,就可以使用concat()方法將它們組合為finalArgs,然后使用apply()將結(jié)果傳遞給函數(shù)。注意這個(gè)函數(shù)并沒(méi)有考慮到執(zhí)行環(huán)境,所以調(diào)用apply()時(shí)第一個(gè)參數(shù)是null。curry()函數(shù)可以按以下方式應(yīng)用。

function add(num1, num2) {
    return num1 + num2;
}
var curriedAdd = curry(add, 5);
alert(curriedAdd(3)); //8

在這個(gè)例子中,創(chuàng)建了第一個(gè)參數(shù)綁定為5的add()的柯里化版本。當(dāng)調(diào)用cuurriedAdd()并傳入3時(shí),3會(huì)成為add()的第二個(gè)參數(shù),同時(shí)第一個(gè)參數(shù)依然是5,最后結(jié)果便是和8。也可以像下例這樣給出所有的函數(shù)參數(shù):

function add(num1, num2) {
    return num1 + num2;
}
var curriedAdd2 = curry(add, 5, 12);
alert(curriedAdd2()); //17

在這里,柯里化的add()函數(shù)兩個(gè)參數(shù)都提供了,所以以后就無(wú)需再傳遞給它們了,函數(shù)柯里化還常常作為函數(shù)綁定的一部分包含在其中,構(gòu)造出更為復(fù)雜的bind()函數(shù)。

function bind(fn, context) {
    var args = Array.prototype.slice.call(arguments, 2);
    return function() {
        var innerArgs = Array.prototype.slice.call(arguments),
        finalArgs = args.concat(innerArgs);
        return fn.apply(context, finalArgs);
    };
}

對(duì)curry()函數(shù)的主要更改在于傳入的參數(shù)個(gè)數(shù),以及它如何影響代碼的結(jié)果。curry()僅僅接受一個(gè)要包裹的函數(shù)作為參數(shù),而bind()同時(shí)接受函數(shù)和一個(gè)object對(duì)象。

這表示給被綁定的函數(shù)的參數(shù)是從第三個(gè)開(kāi)始而不是第二個(gè),這就要更改slice()的第一處調(diào)用。另一處更改是在倒數(shù)第3行將object對(duì)象傳給apply()。當(dāng)使用bind()時(shí),它會(huì)返回綁定到給定環(huán)境的函數(shù),并且可能它其中某些函數(shù)參數(shù)已經(jīng)被設(shè)好。

要想除了event對(duì)象再額外給事件處理程序傳遞參數(shù)時(shí),這非常有用。

var handler = {
    message: "Event handled",
    handleClick: function(name, event){
        alert(this.message + ":" + name + ":" + event.type);
    }
};var btn = document.getElementById("my-btn");
EventUtil.addHandler(btn, "click", bind(handler.handleClick, handler, "my-btn"));

handler.handleClick()方法接受了兩個(gè)參數(shù):要處理的元素的名字和event對(duì)象。作為第三個(gè)參數(shù)傳遞給bind()函數(shù)的名字,又被傳遞給了handler.handleClick(),而handler.handleClick()也會(huì)同時(shí)接收到event對(duì)象。

ECMAScript5的bind()方法也實(shí)現(xiàn)函數(shù)柯里化,只要在this的值之后再傳入另一個(gè)參數(shù)即可。

var handler = {
    message: "Event handled",
    handleClick: function(name, event) {
        alert(this.message + ":" + name + ":" + event.type);
    }
};
var btn = document.getElementById("my-btn");
EventUtil.addHandler(btn, "click", handler.handleClick.bind(handler, "my-btn"));

javaScript中的柯里化函數(shù)和綁定函數(shù)提供了強(qiáng)大的動(dòng)態(tài)函數(shù)創(chuàng)建功能。使用bind()還是curry()要根據(jù)是否需要object對(duì)象響應(yīng)來(lái)決定。它們都能用于創(chuàng)建復(fù)雜的算法和功能,當(dāng)然兩者都不應(yīng)濫用,因?yàn)槊總€(gè)函數(shù)都會(huì)帶來(lái)額外的開(kāi)銷。

關(guān)于“JavaScript函數(shù)柯里化有什么用”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI