摘要:忍者秘籍一書中,對于柯里化的定義如下在一個函數(shù)中首先填充幾個參數(shù)然后再返回一個新函數(shù)的技術稱為柯里化?;氐轿覀兊念}目本身,其實根據(jù)測試用例我們可以發(fā)現(xiàn),函數(shù)的要求就是接受單一函數(shù),例如但是與柯里化不同之處在于,柯里化返回的一個新函數(shù)。
歡迎大家再一次來到我的文章專欄:從面試題中我們能學到什么,各位同行小伙伴是否已經(jīng)開始了悠閑的春節(jié)假期呢?在這里提前祝大家雞年大吉吧~哈哈,之前有人說,學面試題不會有什么長進,其實我覺得這個就像是我們英語考試中的閱讀理解,帶著問題去看文章反而更有利于自己的學習。
之前的兩篇文章:
一道頗有難度的JavaScript題
一個小小的JavaScript題目
都在稀土掘金和Segmentfault都獲得了非常多的點擊量,沒有看的小伙伴們可以點擊了解一下,今天為大家?guī)硪坏狸P于閉包和函數(shù)的柯里化方面的編程題目,各位小伙伴有沒有開始躍躍欲試呢?
編程題目的要求如下,完成plus函數(shù),通過全部的測試用例。
"use strict"; function plus(n){ } module.exports = plus
測試用例如下
"use strict"; var assert = require("assert") var plus = require("../lib/assign-4") describe("閉包應用",function(){ it("plus(0) === 0",function(){ assert.equal(0,plus(0).toString()) }) it("plus(1)(1)(2)(3)(5) === 12",function(){ assert.equal(12,plus(1)(1)(2)(3)(5).toString()) }) it("plus(1)(4)(2)(3) === 10",function(){ assert.equal(10,plus(1)(4)(2)(3).toString()) }) it("方法引用",function(){ var plus2 = plus(1)(1) assert.equal(12,plus2(1)(4)(2)(3).toString()) }) })
實話說剛開始拿到這道題的時候我并沒有完全的做出來,但是具體的思路是有的,肯定是關于函數(shù)的柯里化(Currying)方面的,應該是想考察一下面試者的閉包理解能力.
那么首先介紹一下什么是函數(shù)的柯里化(Currying)?!禞avaScript忍者秘籍》一書中,對于柯里化的定義如下:
在一個函數(shù)中首先填充幾個參數(shù)(然后再返回一個新函數(shù))的技術稱為柯里化(Currying。
維基百科中關于其定義如下:
在計算機科學中,柯里化(Currying),又譯為卡瑞化或加里化,是把接受多個參數(shù)的函數(shù)變換成接受一個單一參數(shù)(最初函數(shù)的第一個參數(shù))的函數(shù),并且返回接受余下的參數(shù)而且返回結果的新函數(shù)的技術。這個技術由克里斯托弗·斯特雷奇以邏輯學家哈斯凱爾·加里命名的。
首先我們舉個例子來具體的解釋一下以上的概念。
例如一個最簡單的加法函數(shù):
//函數(shù)定義 function add(x,y){ return x + y; } //函數(shù)調用 add(3,4);//5
如果采用柯里化是怎樣將接受兩個參數(shù)的函數(shù)變成接受單一參數(shù)的函數(shù)呢,其實很簡單如下:
//函數(shù)表達式定義 var add = function(x){ return function(y){ return x + y; } }; //函數(shù)調用 add(3)(4);
這樣理解起來其實是不是就很簡單了,其實實質利用的就是閉包的概念(大家可以在我的另一篇文章淺談JavaScript閉包看一下)。本質上講柯里化(Currying)只是一個理論模型,柯里化所要表達是:如果你固定某些參數(shù),你將得到接受余下參數(shù)的一個函數(shù),所以對于有兩個變量的函數(shù)y^x,如果固定了y=2,則得到有一個變量的函數(shù)2^x。這就是求值策略中的部分求值策略。
柯里化(Currying)具有:延遲計算、參數(shù)復用、動態(tài)生成函數(shù)的作用。例如如果我們需要創(chuàng)建一個通用的DOM事件綁定函數(shù),不使用柯里化的寫法如下(該示例來自于博客園Tong Zeng):
//第四個參數(shù)用來標識是在冒泡階段還是在捕獲階段執(zhí)行函數(shù) var addEvent = function(el,type,fn,capture){ if (window.addEventListener) { el.addEventListener(type, function(e) { fn.call(el, e); }, capture); } else if (window.attachEvent) { el.attachEvent("on" + type, function(e) { fn.call(el, e); }); } }
但是在使用了柯里化(Currying)的情況下,不再需要每次添加事件處理都要執(zhí)行一遍if...else...判斷,只需要在瀏覽器中判定一次就可以了,把根據(jù)一次判定之后的結果動態(tài)生成新的函數(shù),以后就不必重新計算。其實在實際使用中使用最多的一個柯里化的例子就是Function.prototype.bind()函數(shù),我們也一并給出一個較為簡單的Function.prototype.bind()函數(shù)的實現(xiàn)方式。
Function.prototype.bind = function(){ var fn = this; var args = Array.prototye.slice.call(arguments); var context = args.shift(); return function(){ return fn.apply(context, args.concat(Array.prototype.slice.call(arguments))); }; };
回到我們的題目本身,其實根據(jù)測試用例我們可以發(fā)現(xiàn),plus函數(shù)的要求就是接受單一函數(shù),例如:
plus(1)(4)(2)(3).toString()
但是與柯里化不同之處在于,柯里化返回的一個新函數(shù)。我們觀察其實最后的求值是通過toString函數(shù)得到的,那么我們就很容易想到,我們可以給返回的函數(shù)增加一個toString屬性就可以了。我自己寫出的答案如下:
/** * Created by lei.wang on 2017/1/22. */ "use strict"; function plus(num) { var adder = function () { var _args = []; var _adder = function _adder() { [].push.apply(_args, [].slice.call(arguments)); return _adder; }; _adder.toString = function () { return _args.reduce(function (a, b) { return a + b; }); } return _adder; } return adder()(num); } module.exports = plus;
運行一下,通過全部的測試用例,需要注意的是由于題目的要求運行在嚴格模式下,所以我們在_adder函數(shù)內部是不能引用arguments.callee,這時我們采用的方法是給函數(shù)表達式中函數(shù)本身起名_adder,這樣就解決的這個問題。
再次感謝大家閱讀本篇文章,希望大家能從中或多或少學到一些東西,入行資歷甚淺,不足之處請多指教,歡迎大家在去我的博客MrErHu中留言打賞,愿大家一同進步。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/81316.html
摘要:對于函數(shù)的柯里化應該不陌生,簡單來說技術是一種通過把多個參數(shù)填充到函數(shù)體中,實現(xiàn)將函數(shù)轉換為一個新的經(jīng)過簡化的使之接受的參數(shù)更少函數(shù)的技術。 對于函數(shù)的柯里化(currying)應該不陌生,簡單來說 Currying 技術是一種通過把多個參數(shù)填充到函數(shù)體中,實現(xiàn)將函數(shù)轉換為一個新的經(jīng)過簡化的(使之接受的參數(shù)更少)函數(shù)的技術。當發(fā)現(xiàn)正在調用同一個函數(shù)時,并且傳遞的參數(shù)絕大多數(shù)都是相同的,...
摘要:如果你對函數(shù)式編程有一定了解,函數(shù)柯里化是不可或缺的,利用函數(shù)柯里化,可以在開發(fā)中非常優(yōu)雅的處理復雜邏輯。同樣先看簡單版本的方法,以方法為例,代碼來自高級程序設計加強版實現(xiàn)上面函數(shù),可以換成任何其他函數(shù),經(jīng)過函數(shù)處理,都可以轉成柯里化函數(shù)。 我們經(jīng)常說在Javascript語言中,函數(shù)是一等公民,它們本質上是十分簡單和過程化的??梢岳煤瘮?shù),進行一些簡單的數(shù)據(jù)處理,return 結果,...
摘要:碰到這種面試官,你只有是個題霸,再加上眼緣夠才能順利入圍。只要按照我題目的思路,甚至打出來測試用例看看,就能實現(xiàn)這個題目了。答案根據(jù)的,對答案做出修正。另我的答案絕不敢稱最佳,隨時歡迎優(yōu)化修正。但了解總歸是好的。 我們在長期的面試過程中,經(jīng)歷了種種苦不堪言,不訴苦感覺不過癮(我盡量控制),然后主要聊聊常見JavaScript面試題的解法,以及面試注意事項 憶苦 面試第一苦,面試官的土 ...
摘要:接下來的函數(shù)就有點難度了,讓我們一行一行來看。上面實際的含義就是將數(shù)組每一個執(zhí)行的返回值保存的數(shù)組中。需要注意的是,方法返回值并不是數(shù)組,而是形如初始值的經(jīng)過疊加處理后的操作。從而實現(xiàn)異步的。 這段時間都在學習Redux,感覺對我來說初學難度很大,中文官方文檔讀了好多遍才大概有點入門的感覺,小小地總結一下,首先可以看一下Redux的基本流程:showImg(https://segm...
摘要:面試題實現(xiàn)結果,題的核心就是問的的柯里化先說說什么是柯里化,看過許多關于柯里化的文章,始終搞不太清楚,例如柯里化是把接受多個參數(shù)的函數(shù)變換成接受一個單一參數(shù)最初函數(shù)的第一個參數(shù)的函數(shù),并且返回接受余下的參數(shù)且返回結果的新函數(shù)的技術。 面試題:實現(xiàn)add(1)(2)(3) //結果 = 6,題的核心就是問的js的柯里化 先說說什么是柯里化,看過許多關于柯里化的文章,始終搞不太清楚,例如...
閱讀 2660·2023-04-26 00:56
閱讀 2079·2021-10-25 09:46
閱讀 1317·2019-10-29 15:13
閱讀 886·2019-08-30 15:54
閱讀 2273·2019-08-29 17:10
閱讀 2682·2019-08-29 15:43
閱讀 548·2019-08-29 15:28
閱讀 3103·2019-08-29 13:24