国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

詳細介紹JavaScript函數柯里化的一些思考

來源:懂視網 責編:小采 時間:2020-11-27 20:24:21
文檔

詳細介紹JavaScript函數柯里化的一些思考

詳細介紹JavaScript函數柯里化的一些思考:1. 高階函數的坑在學習柯里化之前,我們首先來看下面一段代碼:var f1 = function(x){ return f(x); }; f1(x);很多同學都能看出來,這些寫是非常傻的,因為函數f1和f是等效的,我們直接令var f1 = f;就行了,完全沒有必要包裹那么一層。但是,下面一段代碼
推薦度:
導讀詳細介紹JavaScript函數柯里化的一些思考:1. 高階函數的坑在學習柯里化之前,我們首先來看下面一段代碼:var f1 = function(x){ return f(x); }; f1(x);很多同學都能看出來,這些寫是非常傻的,因為函數f1和f是等效的,我們直接令var f1 = f;就行了,完全沒有必要包裹那么一層。但是,下面一段代碼

3. 函數柯里化進一步思考

如果說上一節的例子中,我們不是直接運行f(x),而是把函數f當做一個參數,結果會怎樣呢?我們來看下面這個例子:

假設f1返回函數gg的作用域指向xs,函數f作為g的參數。最終我們可以寫成如下形式:

var f1 = function(f,xs){
 return g.call(xs,f);
};

實際上,用f1來替代g.call(xxx)的做法叫反柯里化。例如:

var forEach = function(xs,f){
 return Array.prototype.forEach.call(xs,f);
};
var f = function(x){console.log(x);};
var xs = {0:'peng',1:'chen',length:2};
forEach(xs,f);

反curring就是把原來已經固定的參數或者this上下文等當作參數延遲到未來傳遞。
它能夠在很大程度上簡化函數,前提是你得習慣它。

拋開反柯里化,如果我們要柯里化f1怎么辦?

使用閉包,我們可以寫成如下形式:

var f1 = function(f){
 return function(xs){
 return g.call(xs,f);
 }
};
var f2 = f1(f);
f2(xs);

f傳入f1中,我們就可以得到f2這個新函數。

只傳給函數一部分參數通常也叫做局部調用(partial application),能夠大量減少樣板文件代碼(boilerplate code)。

當然,函數f1傳入的兩個參數不一定非得包含函數+非函數,可能兩個都是函數,也可能兩個都是非函數。

我個人覺得柯里化并非是必須的,而且不熟悉的同學閱讀起來可能會遇到麻煩,但是它能幫助我們理解JS中的函數式編程,更重要的是,我們以后在閱讀類似的代碼時,不會感到陌生。知乎上羅宸同學講的挺好:

并非“柯里化”對函數式編程有意義。而是,函數式編程在把函數當作一等公民的同時,就不可避免的會產生“柯里化”這種用法。所以它并不是因為“有什么意義”才出現的。當然既然存在了,我們自然可以探討一下怎么利用這種現象。

練習:

// 通過局部調用(partial apply)移除所有參數
var filterQs = function(xs) {
 return filter(function(x){ return match(/q/i, x); }, xs);
};
//這兩個函數原題沒有,是我自己加的
var filter = function(f,xs){
 return xs.filter(f);
};
var match = function(what,x){
 return x.match(what);
};

分析:函數filterQs的作用是:傳入一個字符串數組,過濾出包含’q'的字符串,并組成一個新的數組返回。

我們可以通過如下步驟得到函數filterQs

a. filter傳入的兩個參數,第一個是回調函數,第二個是數組,filter主要功能是根據回調函數過濾數組。我們首先將filter函數柯里化:

var filter = function(f){
 return function (xs) {
 return xs.filter(f);
 }
};

b. 其次,filter函數傳入的回調函數是matchmatch的主要功能是判斷每個字符串是否匹配what這個正則表達式。這里我們將match也柯里化:

var match = function(what){
 return function(x){
 return x.match(what);
 }
};
var match2 = match(/q/i);

創建匹配函數match2,檢查字符串中是否包含字母q。

c. 把match2傳入filter中,組合在一起,就形成了一個新的函數:

var filterQs = filter(match2);
var xs = ['q','test1','test2'];
filterQs(xs);

從這個示例中我們也可以體會到函數柯里化的強大。所以,柯里化還有一個重要的功能:封裝不同功能的函數,利用已有的函數組成新的函數。

4. 函數柯里化的遞歸調用

函數柯里化還有一種有趣的形式,就是函數可以在閉包中調用自己,類似于函數遞歸調用。如下所示:

function add( seed ) {
 function retVal( later ) {
 return add( seed + later );
 }
 retVal.toString = function() {
 return seed;
 };
 return retVal;
}
console.log(add(1)(2)(3).toString()); // 6

add函數返回閉包retVal,在retVal中又繼續調用add,最終我們可以寫成add(1)(2)(3)(...)這樣柯里化的形式。
關于這段代碼的解答,知乎上的李宏訓同學回答地很好:

每調用一次add函數,都會返回retValue函數;調用retValue函數會調用add函數,然后還是返回retValue函數,所以調用add的結果一定是返回一個retValue函數。add函數的存在意義只是為了提供閉包,這個類似的遞歸調用每次調用add都會生成一個新的閉包。

5. 函數組合(compose)

函數組合是在柯里化基礎上完成的:

var compose = function(f,g) {
 return function(x) {
 return f(g(x));
 };
};
var f1 = compose(f,g);
f1(x);

將傳入的函數變成兩個,通過組合的方式返回一個新的函數,讓代碼從右向左運行,而不是從內向外運行。

函數組合和柯里化有一個好處就是pointfree。

pointfree 模式指的是,永遠不必說出你的數據。它的意思是說,函數無須提及將要操作的數據是什么樣的。一等公民的函數、柯里化(curry)以及組合協作起來非常有助于實現這種模式。

// 非 pointfree,因為提到了數據:name
var initials = function (name) {
 return name.split(' ').map(compose(toUpperCase, head)).join('. ');
};

// pointfree
var initials = compose(join('. '), map(compose(toUpperCase, head)), split(' '));

initials("hunter stockton thompson");
// 'H. S. T'

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

詳細介紹JavaScript函數柯里化的一些思考

詳細介紹JavaScript函數柯里化的一些思考:1. 高階函數的坑在學習柯里化之前,我們首先來看下面一段代碼:var f1 = function(x){ return f(x); }; f1(x);很多同學都能看出來,這些寫是非常傻的,因為函數f1和f是等效的,我們直接令var f1 = f;就行了,完全沒有必要包裹那么一層。但是,下面一段代碼
推薦度:
標簽: js 簡介 函數
  • 熱門焦點

最新推薦

猜你喜歡

熱門推薦

專題
Top
主站蜘蛛池模板: 91精品国产99久久 | 欧美成性色 | 大黄毛片 | 九九啪 | 欧美中日韩在线 | 国产精品久久久久9999 | 中文国产成人精品久久96 | 国产成人91一区二区三区 | 国产精品免费观看视频播放 | 久久久无码精品亚洲日韩按摩 | 亚洲欧美影视 | 欧美日韩1区 | 又黄又爽视频在线观看 | 亚洲小视频在线 | 欧美日韩 在线播放 | 久久精品国内一区二区三区 | 一区二区视频 | 真实和子乱视频 | 欧美精品色精品一区二区三区 | 国产不卡网 | 在线国产高清 | 亚洲v日韩v欧美在线观看 | 日韩欧美在线综合 | 人成精品视频三区二区一区 | 最新国产精品精品视频 | 国产成人乱码一区二区三区 | 免费在线观看中文字幕 | 欧美精品国产综合久久 | 男女全黄一级带免费 | 国产在线视频不卡 | 欧美wwww| 免费一级淫片 | 精品亚洲一区二区三区 | 国产成人a一区二区 | 日韩欧美 在线播放 | 黄色在线观看网站 | 国内一区二区 | 日韩www视频 | 色另类| 国产精品一区二区久久不卡 | 悠悠久久|