国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

一道題看透函數(shù)柯里化

marser / 3408人閱讀

摘要:對于函數(shù)的柯里化應(yīng)該不陌生,簡單來說技術(shù)是一種通過把多個(gè)參數(shù)填充到函數(shù)體中,實(shí)現(xiàn)將函數(shù)轉(zhuǎn)換為一個(gè)新的經(jīng)過簡化的使之接受的參數(shù)更少函數(shù)的技術(shù)。

對于函數(shù)的柯里化(currying)應(yīng)該不陌生,簡單來說 Currying 技術(shù)是一種通過把多個(gè)參數(shù)填充到函數(shù)體中,實(shí)現(xiàn)將函數(shù)轉(zhuǎn)換為一個(gè)新的經(jīng)過簡化的(使之接受的參數(shù)更少)函數(shù)的技術(shù)。當(dāng)發(fā)現(xiàn)正在調(diào)用同一個(gè)函數(shù)時(shí),并且傳遞的參數(shù)絕大多數(shù)都是相同的,那么用一個(gè)Curry化的函數(shù)是一個(gè)很好的選擇.

下面利用閉包實(shí)現(xiàn)一個(gè)curry化的加法函數(shù), 我們簡單理解一下 curry 化:

function add(x, y){
    if(x && y) return x + y;
    if(!x && !y) throw Error("Cannot calculate");
    return function(newx){
        return x + newx;
    };
}
add(3)(4); //7
add(3, 4); //7
var newAdd = add(5);
newAdd(8); //13
var add2000 = add(2000);
add2000(100); //2100

這樣做其實(shí)很類似 bind:

function add(a, b){
  console.log(a+b);
  return a + b;
}

add(3, 4);   //7
add.bind(null, 3)(4);   //7
var newAdd = add.bind(null, 5);
newAdd(8);   //13
var add2000 = add.bind(null, 2000);
add2000(100); //2100

同理也可以使用 call 和 apply, 因?yàn)樗麄兛梢詫?shí)現(xiàn) bind 的功能:

Function.prototype.bind = function(context){
  var _this = this;
  var args = [].slice.call(arguments, 1);

  return function (){
    innerArgs = [].slice.call(arguments);
    if(innerArgs && innerArgs.length > 0)
      args.push.apply(args, innerArgs);
    return _this.apply(context, args);
  }
}
add(3, 4);   //7
add.bind(null, 3)(4);   //7
var newAdd = add.bind(null, 5);
newAdd(8);   //13
var add2000 = add.bind(null, 2000);
add2000(100); //2100

但是,如果看到了這個(gè)題:

實(shí)現(xiàn)一個(gè)函數(shù)sum,運(yùn)算結(jié)果可以滿足如下預(yù)期結(jié)果:
sum(1,2,3);       //6
sum(2,3)(2);      //7
sum(1)(2)(3)(4);  //10
sum(2)(4,1)(2);   //9

還覺得簡單么?我們理一下思路。首先試想一下這個(gè) sum 函數(shù)的結(jié)構(gòu):

function sum(){
  return function(){
    return function(){
      //...
    }
  }
}

這個(gè)函數(shù)返回的一定是個(gè)函數(shù),但貌似需要寫無限個(gè),這個(gè)不合理,我們修改一下:

function sum(){
  function innerSum(){
    //...
    return innerSum();
  }
  return innerSum();
}

這樣一來每次調(diào)用就不需要定義無限個(gè)函數(shù)了。我們完善里面的代碼:

//sum(1,2,3);       //6
//sum(2,3)(2);      //7
//sum(1)(2)(3)(4);  //10
//sum(2)(4,1)(2);   //9
function sum(){
  var cur = [].slice.call(arguments).reduce(function(a,b){return a+b;},0);
  function innerSum(){
    var next = [].slice.call(arguments).reduce(function(a,b){return a+b;},0);
    cur += next;
    return innerSum;
  }
  return innerSum;
}

這樣 sum 函數(shù)的柯里化過程就完成了,但是這個(gè)函數(shù)的返回的總是一個(gè)函數(shù),這樣我們?nèi)绾屋敵鰯?shù)值呢?我們可以借助隱式類型轉(zhuǎn)換需要的 toString 函數(shù)實(shí)現(xiàn):

function sum(){
  var cur = [].slice.call(arguments).reduce(function(a,b){return a+b;},0);
  function innerSum(){
    var next = [].slice.call(arguments).reduce(function(a,b){return a+b;},0);
    cur += next;
    return innerSum;
  }
  innerSum.toString = function(){
    return cur;
  }
  return innerSum;
}
console.log(sum(1,2,3));       //6
console.log(sum(2,3)(2));      //7
console.log(sum(1)(2)(3)(4));  //10
console.log(sum(2)(4,1)(2));   //9

計(jì)算結(jié)果沒錯(cuò),我們還可以換作 valueOf 實(shí)現(xiàn):

function sum(){
  var cur = [].slice.call(arguments).reduce(function(a,b){return a+b;},0);
  function innerSum(){
    var next = [].slice.call(arguments).reduce(function(a,b){return a+b;},0);
    cur += next;
    return innerSum;
  }
  innerSum.valueOf = function(){
    return cur;
  }
  return innerSum;
}
console.log(sum(1,2,3));       //6
console.log(sum(2,3)(2));      //7
console.log(sum(1)(2)(3)(4));  //10
console.log(sum(2)(4,1)(2));   //9

其實(shí),如果同時(shí)存在 toString 和 valueOf 系統(tǒng)會(huì)先調(diào)用 toString, 然后調(diào)用valueOf,返回值自然是 valueOf 的返回值。這個(gè)很基礎(chǔ),這里就不提了。

通用柯里化方法

通用的柯里化寫法其實(shí)比之前的 sum 函數(shù)要簡單許多

var currying = function(fn) {
  // 主要還是收集所有需要的參數(shù)到一個(gè)數(shù)組中,便于統(tǒng)一計(jì)算
  var args = [].slice.call(arguments, 1);
  return function(){
      var _args = args.concat([].slice.call(arguments));
      return fn.apply(null, _args);
  }
}

var sum = function(){
  var args = [].slice.call(arguments);
  return args.reduce(function(a, b) {
      return a + b;
  });
};

var sum10 = currying(sum, 10);
console.log(sum10(20, 10));  // 40
console.log(sum10(10, 5));   // 25

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/107628.html

相關(guān)文章

  • 一道面試談?wù)?em>函數(shù)柯里(Currying)

    摘要:忍者秘籍一書中,對于柯里化的定義如下在一個(gè)函數(shù)中首先填充幾個(gè)參數(shù)然后再返回一個(gè)新函數(shù)的技術(shù)稱為柯里化。回到我們的題目本身,其實(shí)根據(jù)測試用例我們可以發(fā)現(xiàn),函數(shù)的要求就是接受單一函數(shù),例如但是與柯里化不同之處在于,柯里化返回的一個(gè)新函數(shù)。   歡迎大家再一次來到我的文章專欄:從面試題中我們能學(xué)到什么,各位同行小伙伴是否已經(jīng)開始了悠閑的春節(jié)假期呢?在這里提前祝大家雞年大吉吧~哈哈,之前有人說...

    cppprimer 評論0 收藏0
  • 一道面試認(rèn)識(shí)函數(shù)柯里

    摘要:函數(shù)柯里化在函數(shù)式編程中,函數(shù)是一等公民。函數(shù)柯里化的主要作用和特點(diǎn)就是參數(shù)復(fù)用提前返回和延遲執(zhí)行。可能在實(shí)際應(yīng)用場景中,很少使用函數(shù)柯里化的解決方案,但是了解認(rèn)識(shí)函數(shù)柯里化對自身的提升還是有幫助的。 最近在整理面試資源的時(shí)候,發(fā)現(xiàn)一道有意思的題目,所以就記錄下來。 題目 如何實(shí)現(xiàn) multi(2)(3)(4)=24? 首先來分析下這道題,實(shí)現(xiàn)一個(gè) multi 函數(shù)并依次傳入?yún)?shù)執(zhí)行,...

    13651657101 評論0 收藏0
  • 一道柯里面試

    摘要:這是一道朋友在群里發(fā)的一道題,我之前不是很懂柯里化,就自己試著寫了一下,不知道算不算柯里化,望指教下面是題目寫好之后一下代碼可以正常運(yùn)行輸入正確我自己的代碼我用到了以下知識(shí)點(diǎn)擴(kuò)展運(yùn)算符傳參和擴(kuò)展運(yùn)算符相關(guān)的數(shù)組操作。 這是一道朋友在群里發(fā)的一道題,我之前不是很懂柯里化,就自己試著寫了一下,不知道算不算柯里化,望指教~ 下面是題目: function curry() { ...

    andycall 評論0 收藏0
  • 關(guān)于JavaScript函數(shù)柯里探索

    摘要:函數(shù)柯里化關(guān)于函數(shù)柯里化的問題最初是在忍者秘籍中講閉包的部分中看到的,相信很多同學(xué)見過這樣一道和柯里化有關(guān)的面試題實(shí)現(xiàn)一個(gè)函數(shù),使得如下斷言能夠能夠通過簡單說就是實(shí)現(xiàn)一個(gè)求值函數(shù),能夠?qū)⑺袇?shù)相加得出結(jié)果。方法返回一個(gè)表示該對象的字符串。 函數(shù)柯里化 ??關(guān)于函數(shù)柯里化的問題最初是在《JavaScript忍者秘籍》中講閉包的部分中看到的,相信很多同學(xué)見過這樣一道和柯里化有關(guān)的面試題:...

    vboy1010 評論0 收藏0
  • 「前端面試系列6」理解函數(shù)柯里

    摘要:原題如下寫一個(gè)方法,當(dāng)使用下面的語法調(diào)用時(shí),能正常工作這道題要考察的,就是對函數(shù)柯里化的理解。當(dāng)參數(shù)只有一個(gè)的時(shí)候,進(jìn)行柯里化的處理。這其實(shí)就是函數(shù)柯里化的簡單應(yīng)用。 showImg(https://segmentfault.com/img/bVbopGm?w=620&h=350); 前言 這是前端面試題系列的第 6 篇,你可能錯(cuò)過了前面的篇章,可以在這里找到: ES6 中箭頭函數(shù)的...

    liaorio 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<