JS中的柯里化 currying

2022-06-16 22:33:18 字數 4340 閱讀 1882

curry化**與數學家 haskell curry的名字 (程式語言 haskell也是以他的名字命名)。

柯里化通常也稱部分求值,其含義是給函式分步傳遞引數,每次傳遞引數後部分應用引數,並返回乙個更具體的函式接受剩下的引數,這中間可巢狀多層這樣的接受部分引數函式,直至返回最後結果。

因此柯里化的過程是逐步傳參,逐步縮小函式的適用範圍,逐步求解的過程。

按照分步求值,我們看乙個簡單的例子

var concat3words = function

(a, b, c) ;

var concat3wordscurrying = function

(a) ;

};};console.log(concat3words("foo ","bar ","baza")); //

foo bar baza

console.log(concat3wordscurrying("foo ")); //

[function]

console.log(concat3wordscurrying("foo ")("bar ")("baza")); //

foo bar baza

可以看到, concat3wordscurrying("foo ") 是乙個 function,每次呼叫都返回乙個新的函式,該函式接受另乙個呼叫,然後又返回乙個新的函式,直至最後返回結果,分布求解,層層遞進。(ps:這裡利用了閉包的特點)

那麼現在我們更進一步,如果要求可傳遞的引數不止3個,可以傳任意多個引數,當不傳引數時輸出結果?

首先來個普通的實現:

var add = function

(items));

};console.log(add([1,2,3,4]));

但如果要求把每個數乘以10之後再相加,那麼:

var add = function

(items,multi) ).reduce(

function

(a, b) );

};console.log(add([1, 2, 3, 4],10));

好在有 map 和 reduce 函式,假如按照這個模式,現在要把每項加1,再彙總,那麼我們需要更換map中的函式。

下面看一下柯里化實現:

var adder = function

() );

}return

arguments.callee;

}};

var sum =adder();

console.log(sum);

//function

sum(100,200)(300); //

呼叫形式靈活,一次呼叫可輸入乙個或者多個引數,並且支援鏈式呼叫

sum(400);

console.log(sum());

//1000 (加總計算)

上面 adder是柯里化了的函式,它返回乙個新的函式,新的函式接收可分批次接受新的引數,延遲到最後一次計算。

更典型的柯里化會把最後一次的計算封裝進乙個函式中,再把這個函式作為引數傳入柯里化函式,這樣即清晰,又靈活。

例如 每項乘以10, 我們可以把處理函式作為引數傳入:

var currying = function

(fn)

return

arguments.callee;

}};var multi=function

()

return

total;

};var sum =currying(multi);

sum(100,200)(300);

sum(400);

console.log(sum());

//1000 (空白呼叫時才真正計算)

這樣 sum = currying(multi),呼叫非常清晰,使用效果也堪稱絢麗,例如要累加多個值,可以把多個值作為做個引數 sum(1,2,3),也可以支援鏈式的呼叫,sum(1)(2)(3)

var addevent = function

(el, type, fn, capture) , capture);

} else

if(window.attachevent) );

} };

每次新增事件處理都要執行一遍 if...else...,其實在乙個瀏覽器中只要一次判定就可以了,把根據一次判定之後的結果動態生成新的函式,以後就不必重新計算。

var addevent = (function

(), (capture));

};}

else

if(window.attachevent) );};}

})();

這個例子,第一次 if...else... 判斷之後,完成了部分計算,動態建立新的函式來處理後面傳入的引數,這是乙個典型的柯里化。

var foo = ;

var bar = function

() .bind(foo);

//繫結

bar(); //

888

下面是乙個 bind 函式的模擬,testbind 建立並返回新的函式,在新的函式中將真正要執行業務的函式繫結到實參傳入的上下文,延遲執行了。

function.prototype.testbind = function

(scope)

};var testbindbar = bar.testbind(foo); //

繫結 foo,延遲執行

console.log(testbindbar); //

function (可見,bind之後返回的是乙個延遲執行的新函式)

testbindbar();

這裡要注意 prototype 中 this 的理解。

給bar傳遞引數,如下:

var foo =

var bar = function

(e)

function.prototype.testbind = function

(scope)

}var test = bar.testbind(foo);//

繫結 foo ,延遲執行

console.log(test); //

test(2323); //

執行, 結果是 888 2323

例項1:

var currying = function

(fn) ;

};//

下為**如何搞定7個老婆的測試

//獲得合法老婆

var getwife = currying(function

() , "合法老婆");

//獲得其他6個老婆

getwife("大老婆","小老婆","俏老婆","刁蠻老婆","乖老婆","送上門老婆");

//換一批老婆

getwife("超越韋小寶的老婆");

結果:

合法老婆;大老婆;小老婆;俏老婆;刁蠻老婆;乖老婆;送上門老婆

合法老婆;超越韋小寶的老婆

例項2:

var curryweight = function

(fn)

else

}};var fishweight = 0;

var addweight = curryweight(function

() });

addweight(2.3);

addweight(6.5);

addweight(1.2);

addweight(2.5);

addweight();

//這裡才計算

console.log(fishweight);

例項3:

"use strict";

var currying = function

(fn)

return

f; })

}var multi = function

()

return

total;

}var sum =currying(multi);

sum(100,200)(300);

var result =sum();

console.log(result)

//600

js 函式柯里化(Currying)

在電腦科學中,柯里化 currying 又譯為卡瑞化或加里化,是把接受多個引數的函式變換成接受乙個單一引數 最初函式的第乙個引數 的函式,並且返回接受餘下的引數而且返回結果的新函式的技術。題目 使用 js 實現 add 1 2 3 4 返回 10 函式柯里化要求多個引數轉為單一引數,所以相當於 fu...

js 函式的柯里化 Currying

1.詳解js函式柯里化 2.函式式編的js curry 維基百科上說道 柯里化,英語 currying 果然是滿滿的英譯中的既視感 是把接受多個引數的函式變換成接受乙個單一引數 最初函式的第乙個引數 的函式,並且返回接受餘下的引數而且返回結果的新函式的技術。舉例 普通的add函式 function ...

swift 之 柯里化 Currying

概念 在電腦科學中,柯里化 currying 是把接受多個引數的函式變換成接受乙個單一引數 最初函式的第乙個引數 的函式,並且返回接受餘下的引數且返回結果的新函式的技術。這個技術由 christopher strachey 以邏輯學家 haskell curry 命名的,儘管它是 moses sch...