摘要:函數(shù)柯里化是指參數(shù)逐漸求值的過程。所以對于有兩個變量的函數(shù),如果固定了,則得到有一個變量的函數(shù)通用實(shí)現(xiàn)先看一個簡單的例子顯然不是一個柯里化的實(shí)現(xiàn)。從一個通用的函數(shù)可接受任意,柯里化成專用的函數(shù)。
函數(shù)柯里化是指參數(shù)逐漸求值的過程。
我覺得它是:降低通用性,提高專用性。
通常,柯里化是這樣的過程,“如果你固定某些參數(shù),你將得到接受余下參數(shù)的一個函數(shù)”。所以對于有兩個變量的函數(shù)y^x,如果固定了 y=2,則得到有一個變量的函數(shù) 2^x
通用實(shí)現(xiàn)
function currying(fn) { var slice = Array.prototype.slice; var args = alice.call(arguments, 1); return function() { var innerArgs = slice.call(arguments); var finalArgs = args.concat(innerArgs); return fn.apply(null, finalArgs); } }
先看一個簡單的例子
function add(num1, num2) { return num1 + num2; } function curryAdd(num) { return num + 5; } add(2, 4); // 6 curryAdd(1); // 6
curryAdd 顯然不是一個柯里化的實(shí)現(xiàn)。但是它很好的詮釋了柯里化的思想。add 函數(shù)有兩個參數(shù),curryAdd 固定了其中一個參數(shù)
用上面 currying 函數(shù)構(gòu)造 curryAdd 函數(shù)。
var curryAdd5 = currying(add, 5); var curryAdd4 = currying(add, 4); curryAdd5(1); // 6 curryAdd4(1); // 5
再看一個經(jīng)典的 ajax 例子。
function Ajax() { this.xhr = new XMLHttpRequest(); } Ajax.prototype.open = function(type, url, data, callback) { this.onload = function() { callback(this.xhr.responseText, this.xhr.status, thix.xhr); } this.xhr.open(type, url, data.async); this.xhr.send(data.paras); } ["get", "post"].forEach(function(type) { Ajax.prototype[type] = currying(Ajax.prototype.open, type); }) var xhr = new Ajax(); xhr.get("/articles/list", {}, function(datas) {}); xhr.post("/articles/add", {}, function(datas) {});
get post 兩個方法是通過 "open" 方法衍生出來的。
固定易變因數(shù)從一個通用的 open 函數(shù)(可接受任意type),柯里化成專用的函數(shù) get、post。
提前把易變因數(shù)固定下來,生成一個更明確的應(yīng)用函數(shù),最典型的代碼就是 ES5 定義的 Function.prototype.bing 函數(shù)
Function.prototype.bing = function(context) { var _this = this, slice = Array.prototype.slice, _args = slice.call(arguments, 1); return function() { return _this.apply(context, _args.concat(slice.call(arguments))) } }延遲執(zhí)行
不斷的柯里化,累積傳入的參數(shù),最后執(zhí)行。
function add() { var sum = 0, i, len; for (i = 0, len = arguments.length; i < len; i++) { sum += arguments[i]; } return sum; } var currying = function(fn) { var _args = []; return function cb() { if (arguments.length === 0) { return fn.apply(this, _args); } Array.prototype.push.apply(_args, arguments); return cb; } } var curryingAdd = currying(add); curryingAdd(1)(2)(3)(4)(); // 10 var add321 = curryingAdd(3)(2, 1); add321(4)(); // 10性能
柯里化肯定會有一些開銷(函數(shù)嵌套,比普通函數(shù)占更多內(nèi)存),但性能瓶頸首先來自其它原因(DOM 操作等)。
從另外一個角度分析,不管你用不用柯里化這個思維,你的代碼很可能已經(jīng)步入了更復(fù)雜的模式,會有更大的開銷。
有關(guān)性能的一些事:
存取 arguments 對象通常要比存取命名參數(shù)要慢一些。
一些老版本的瀏覽器在 arguments.length 的實(shí)現(xiàn)上相當(dāng)慢。
使用 fn.apply() 和 fn.call() 要比直接調(diào)用 fn() 要慢點(diǎn)。
創(chuàng)建大量嵌套作用域和閉包會帶來開銷,無論是內(nèi)容還是速度上。
大多數(shù)瓶頸來自 DOM 操作
總結(jié)柯里化是以邏輯學(xué)家哈斯凱爾·加里命名的,
正如它的命名一樣,函數(shù)柯里化給我們帶來的是:解決問題的一種邏輯思維方式。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/85984.html
摘要:函數(shù)式編程,一看這個詞,簡直就是學(xué)院派的典范。所以這期周刊,我們就重點(diǎn)引入的函數(shù)式編程,淺入淺出,一窺函數(shù)式編程的思想,可能讓你對編程語言的理解更加融會貫通一些。但從根本上來說,函數(shù)式編程就是關(guān)于如使用通用的可復(fù)用函數(shù)進(jìn)行組合編程。 showImg(https://segmentfault.com/img/bVGQuc); 函數(shù)式編程(Functional Programming),一...
摘要:有這樣的說法,并非柯里化有什么意義,而是,當(dāng)函數(shù)可以作為函數(shù)的參數(shù)和返回值,成為函數(shù)式編程語言后,就會不可避免地產(chǎn)生函數(shù)柯里化。函數(shù)柯里化允許和鼓勵你分隔復(fù)雜功能變成更小更容易分析的部分。那么用函數(shù)柯里化就能實(shí)現(xiàn)提前返回。 #### 前言 在計算機(jī)科學(xué)中,柯里化(英語:Currying),又譯為卡瑞化或加里化,是把接受多個參數(shù)的函數(shù)變換成接受一個單一參數(shù)(最初函數(shù)的第一個參數(shù))的函數(shù),...
摘要:作為函數(shù)式編程語言,帶來了很多語言上的有趣特性,比如柯里化和反柯里化。而反柯里化,從字面講,意義和用法跟函數(shù)柯里化相比正好相反,擴(kuò)大適用范圍,創(chuàng)建一個應(yīng)用范圍更廣的函數(shù)。作為函數(shù)式編程語言,JS帶來了很多語言上的有趣特性,比如柯里化和反柯里化。 可以對照另外一篇介紹 JS 柯里化 的文章一起看~ 1. 簡介 柯里化,是固定部分參數(shù),返回一個接受剩余參數(shù)的函數(shù),也稱為部分計算函數(shù),目的是為了縮...
摘要:組合的概念是非常直觀的,并不是函數(shù)式編程獨(dú)有的,在我們生活中或者前端開發(fā)中處處可見。其實(shí)我們函數(shù)式編程里面的組合也是類似,函數(shù)組合就是一種將已被分解的簡單任務(wù)組織成復(fù)雜的整體過程。在函數(shù)式編程的世界中,有這樣一種很流行的編程風(fēng)格。 JavaScript函數(shù)式編程,真香之認(rèn)識函數(shù)式編程(一) 該系列文章不是針對前端新手,需要有一定的編程經(jīng)驗,而且了解 JavaScript 里面作用域,閉...
摘要:作為函數(shù)式編程語言,帶來了很多語言上的有趣特性,比如柯里化和反柯里化。在一些函數(shù)式編程語言中,會定義一個特殊的占位變量。個人理解不知道對不對延遲執(zhí)行柯里化的另一個應(yīng)用場景是延遲執(zhí)行。不斷的柯里化,累積傳入的參數(shù),最后執(zhí)行。作為函數(shù)式編程語言,JS帶來了很多語言上的有趣特性,比如柯里化和反柯里化。 這里可以對照另外一篇介紹 JS 反柯里化 的文章一起看~ 1. 簡介 柯里化(Currying)...
閱讀 4376·2021-09-09 09:33
閱讀 2382·2019-08-29 17:15
閱讀 2370·2019-08-29 16:21
閱讀 972·2019-08-29 15:06
閱讀 2613·2019-08-29 13:25
閱讀 578·2019-08-29 11:32
閱讀 3247·2019-08-26 11:55
閱讀 2587·2019-08-23 18:24