面試題-sum(1,2)(3)函數(shù)柯里化

'庫里'化.jpg

前往->個(gè)人博客可獲得更好的閱讀體驗(yàn)~

題目 
編寫一個(gè)方法sum,使sum(1,2,3) 和 sum(1,2)(3)的輸出都為6

感謝前人指路——詳解JS函數(shù)柯里化

前言

這道題目考的是函數(shù)柯里化的概念

柯里化节猿,英語:Currying(果然是滿滿的英譯中的既視感)抵蚊,是把接受多個(gè)參數(shù)的函數(shù)變換成接受一個(gè)單一參數(shù)(最初函數(shù)的第一個(gè)參數(shù))的函數(shù)凉袱,并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)的技術(shù)。

看概念檩帐,云里霧里茫虽,上例子!

// 普通的add函數(shù)
function add(x, y) {
    return x + y
}

// Currying后
function curryingAdd(x) {
    return function (y) {
        return x + y
    }
}

add(1, 2)     // 3
curryingAdd(1)(2)   // 3

看了例子施籍,主要概念就是讓函數(shù)返回一個(gè)function可以接受第二個(gè)(或者更多)括號(hào)里的參數(shù)并輸出期望值。

思考

針對(duì)這個(gè)題目概漱,需要做的是:
1丑慎、利用閉包創(chuàng)建一個(gè)數(shù)組保存參數(shù)
2、返回一個(gè)方法瓤摧,用于接收下一個(gè)括號(hào)里的參數(shù)
3竿裂、全部接收后,返回所有參數(shù)的和

代碼

限定參數(shù)數(shù)量

如果僅僅針對(duì)題目照弥,我們得到下面的代碼

// 固定數(shù)量參數(shù)
function constSum() {
    // 因?yàn)榫腿齻€(gè)參數(shù)腻异,直接用計(jì)數(shù)器,定義數(shù)組添加參數(shù)这揣,判斷數(shù)組長度也可以
    (this.counter = 0), (this.sumNum = 0);
    let that = this;
    
// ...rest是ES6中參數(shù)解構(gòu)的寫法悔常,函數(shù)中的rest為數(shù)組
    return function innerSum(...rest) {
        rest.forEach((item) => {
            that.counter++;
            that.sumNum += item;
        });
      // 判斷
        if (that.counter === 3) {
            return that.sumNum;
        } else {
            return innerSum;
        }
    };
}

let sum = new constSum();
var result = sum(1, 2)(3);
var result2= sum(1, 2, 3);
console.log(result); // 6  
console.log(resul2); // 6

這樣可以實(shí)現(xiàn)題目中的效果影斑,但是并不好,因?yàn)橄薅ㄋ?個(gè)參數(shù)机打,如果我們希望擁有更靈活通用的方法呢矫户?
比如可以支持sum(1,2,3)(4)(5)......

不限定參數(shù)數(shù)量
// 不限數(shù)量參數(shù)
function sum(...rest) {
  // 第一次執(zhí)行時(shí),定義一個(gè)數(shù)組專門用來存儲(chǔ)所有的參數(shù)
  var _args = Array.prototype.slice.call(arguments); 

  // 在內(nèi)部聲明一個(gè)函數(shù)姐帚,利用閉包的特性保存_args并收集所有的參數(shù)值
   var _adder = function() { 
       _args.push(...arguments); 

      return _adder;
  };

  // 利用toString隱式轉(zhuǎn)換的特性吏垮,當(dāng)最后執(zhí)行時(shí)隱式轉(zhuǎn)換障涯,并計(jì)算最終的值返回
  _adder.toString = function () {
    let sum = _args.reduce(function (a, b) {
      return a + b;
  });
      return sum
  }
  return _adder;
}
console.log(sum(1)(2)(3))              // 6
console.log(sum(1, 2, 3)(4))             // 10
console.log(sum(1)(2)(3)(4)(5))        // 15

以上可以實(shí)現(xiàn)不限定參數(shù)數(shù)量的sum函數(shù)罐旗。
其中Array.prototype.slice.calltoString隱式轉(zhuǎn)換其實(shí)都是js基礎(chǔ)知識(shí)點(diǎn),具體可以另開兩篇文章唯蝶。
但是這里先明白其功能——
一個(gè)是將參數(shù)轉(zhuǎn)換為數(shù)組九秀。
一個(gè)是在返回最后一次執(zhí)行結(jié)束后,return了一個(gè)_adder方法粘我,在輸出時(shí)鼓蜒,正常會(huì)隱式調(diào)用Function.toString的方法,以字符方式輸出方法征字。因?yàn)樯厦娓膶懥薩adder的toString方法都弹,所以最后沒有以字符方式輸出方法,而是隱式調(diào)用了我們改寫的輸出了所有參數(shù)的和的toString方法匙姜。
這樣的方法在chrome可以輸出f 6這樣的數(shù)字畅厢,但如果輸出一下這個(gè)結(jié)果的類型比如——

// ...上略
console.log(typeof sum(1)(2)(3))              // function

我們會(huì)得到這個(gè)結(jié)果的類型其實(shí)還是function。所以這個(gè)方法其實(shí)是很勉強(qiáng)的實(shí)現(xiàn)了題目的效果氮昧,但得到的數(shù)據(jù)不能直接作為Number來使用框杜。
還是需要顯示調(diào)用才能得到number類型的結(jié)果——

// ...上略
let sumToNumber = Number.parseInt(sum(1)(2)(3))
console.log(sumToNumber)              // 6
console.log(typeof sumToNumber)              // number

擴(kuò)展

ES6改寫

使用ES6的不定參數(shù)rest的新特性,該特性可以讓不定參數(shù)變成一個(gè)數(shù)組傳入袖肥,不需要訪問arguments咪辱,也省去了使用Array.prototype.slice.call(arguments);生成數(shù)組,更加優(yōu)雅椎组。

function sumWithES6(...rest) {
    var _args = rest;

    var _adder = function (...innerRest) {
        _args.push(...innerRest); // 這里使用的是ES6數(shù)組的解構(gòu)
        return _adder;
    };

    _adder.toString = function () {
        let sum = _args.reduce(function (a, b) {
            return a + b;
        });
        return sum;
    };
    return _adder;
}

console.log(sumWithES6(1)(2)(3)); // 6
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末油狂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子寸癌,更是在濱河造成了極大的恐慌专筷,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灵份,死亡現(xiàn)場離奇詭異仁堪,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)填渠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門弦聂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸟辅,“玉大人,你說我怎么就攤上這事莺葫》肆梗” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵捺檬,是天一觀的道長再层。 經(jīng)常有香客問我,道長堡纬,這世上最難降的妖魔是什么聂受? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮烤镐,結(jié)果婚禮上蛋济,老公的妹妹穿的比我還像新娘。我一直安慰自己炮叶,他們只是感情好碗旅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著镜悉,像睡著了一般祟辟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上侣肄,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天旧困,我揣著相機(jī)與錄音,去河邊找鬼茫孔。 笑死叮喳,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缰贝。 我是一名探鬼主播馍悟,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼剩晴!你這毒婦竟也來了锣咒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤赞弥,失蹤者是張志新(化名)和其女友劉穎毅整,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绽左,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡悼嫉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拼窥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片戏蔑。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蹋凝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出总棵,到底是詐尸還是另有隱情鳍寂,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布情龄,位于F島的核電站迄汛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏骤视。R本人自食惡果不足惜鞍爱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望尚胞。 院中可真熱鬧硬霍,春花似錦、人聲如沸笼裳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽躬柬。三九已至,卻和暖如春抽减,著一層夾襖步出監(jiān)牢的瞬間允青,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來泰國打工卵沉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留颠锉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓史汗,卻偏偏與公主長得像琼掠,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子停撞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 柯里化是函數(shù)的一個(gè)比較高級(jí)的應(yīng)用瓷蛙,想要理解它并不簡單。因此我一直在思考應(yīng)該如何更加表達(dá)才能讓大家理解起來更加容易戈毒。...
    董石頁閱讀 408評(píng)論 0 0
  • 一埋市、什么是柯里化? 我們先來看看維基百科中是如何定義的:在計(jì)算機(jī)科學(xué)中冠桃,柯里化(英語:Currying),又譯為卡...
    沐向閱讀 3,308評(píng)論 1 5
  • 原文鏈接 Haskell和scala都支持函數(shù)的柯里化,JavaScript函數(shù)的柯里化還與JavaScript的...
    dreamapple閱讀 2,528評(píng)論 0 24
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5道宅? 答:HTML5是最新的HTML標(biāo)準(zhǔn)食听。 注意:講述HT...
    kismetajun閱讀 27,486評(píng)論 1 45
  • 久違的晴天套么,家長會(huì)。 家長大會(huì)開好到教室時(shí)碳蛋,離放學(xué)已經(jīng)沒多少時(shí)間了胚泌。班主任說已經(jīng)安排了三個(gè)家長分享經(jīng)驗(yàn)。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,523評(píng)論 16 22