摘要:背景在下前端小白,近日在刷各種算法編程題,今天碰到一編程題,考點(diǎn)是,雖說(shuō)簡(jiǎn)單,但在解題時(shí)發(fā)現(xiàn)了一個(gè)挺有意思的東東,特來(lái)分享一下。分析及結(jié)論如下原理其實(shí)很簡(jiǎn)單,其實(shí)就是一個(gè)函數(shù),將視為一個(gè)整體,記作。
背景
在下前端小白,近日在刷各種算法/編程題,今天碰到一編程題,考點(diǎn)是apply,雖說(shuō)簡(jiǎn)單,但在解題時(shí)發(fā)現(xiàn)了一個(gè)挺有意思的東東,特來(lái)分享一下。歡迎各位大佬指點(diǎn)~
正文話不多說(shuō),直接上題目:二次封裝函數(shù)。
已知函數(shù) fn 執(zhí)行需要 3 個(gè)參數(shù)。請(qǐng)實(shí)現(xiàn)函數(shù) partial,調(diào)用之后滿足如下條件: 1、返回一個(gè)函數(shù) result,該函數(shù)接受一個(gè)參數(shù) 2、執(zhí)行 result(str3) ,返回的結(jié)果與 fn(str1, str2, str3) 一致
哈哈,這題簡(jiǎn)單!稍微學(xué)過(guò)js的朋友就能寫(xiě)出來(lái):
function partial(fn,str1,str2) { var result = function(str3) { return fn(str1,str2,str3); } return result; }
這里用個(gè)call可能會(huì)顯得有點(diǎn)逼格(笑),當(dāng)然apply,bind也能達(dá)到一樣的效果。
function partial(fn,str1,str2) { var result = function(str3) { return fn.call(null,str1,str2,str3); } return result; }
不多停留,我們來(lái)看下一題,同樣是二次封裝函數(shù):
實(shí)現(xiàn)函數(shù) partialUsingArguments,調(diào)用之后滿足如下條件: 1、返回一個(gè)函數(shù) result 2、調(diào)用 result 之后,返回的結(jié)果與調(diào)用函數(shù) fn 的結(jié)果一致 3、fn 的調(diào)用參數(shù)為 partialUsingArguments 的第一個(gè)參數(shù)之后的全部參數(shù)以及 result 的調(diào)用參數(shù)
emmmmm,傳入的參數(shù)不固定? 有了! 用arguments~
function partialUsingArguments(fn) { var _arguments = Array.prototype.slice.call(arguments,1) var result = function() { var newArguments = _arguments.concat(Array.prototype.slice.call(arguments,0)); return fn.apply(null,newArguments) } return result; }
唔,好像也沒(méi)什么難的,_arguments就是partialUsingArguments第一個(gè)參數(shù)后的所有參數(shù)組成的數(shù)組,將它和result的所有參數(shù)合并起來(lái),利用apply傳入fn,ok~解決了!
誒誒?有意思的東西呢?這特么一點(diǎn)意思都沒(méi)啊。
說(shuō)出來(lái)你們可能不信,其實(shí)我看到這題的時(shí)候,雖然我想到了用apply,但我并沒(méi)有想到fn.apply(null,newArguments)。那我想到的是什么呢?
Function.prototype.call.apply
什么鬼?我也不知道是在哪看過(guò)這東西(也許沒(méi)看過(guò)),又好像是
Function.prototype.call.call?
還是
Function.prototype.apply.apply?
還是
Function.prototype.apply.call?
好像都差不多,媽個(gè)雞,試試就知道了!
return Function.prototype.call.apply(fn,newArguments)
瀏覽器一跑,好像對(duì)了?不對(duì)!我傳入的第一個(gè)參數(shù)怎么不見(jiàn)了?
Google之~ 噢~ 原來(lái)第一個(gè)參數(shù)被吃了。
原來(lái)Function.prototype.call.apply(fn,newArguments)同等于fn.call(a,b,c,...z) // newArguments = [a,b,c,...z],這里的...z不是ES6中的...rest哦,只是表示省略了中間的參數(shù)。
知道了原理(并不知道),那就好辦了,我給newArguments數(shù)組的頭部補(bǔ)一個(gè)元素上去不就好了~
newArguments.unshift(0); Function.prototype.call.apply(fn,newArguments)
瀏覽器一跑——沒(méi)毛病老鐵!
完了嗎?
并沒(méi)有!既然.call.apply可以用,那其他3個(gè)按理來(lái)說(shuō)也能用,況且這里多了一步對(duì)數(shù)組的操作,能不能更優(yōu)雅一點(diǎn)呢?(另外3個(gè)怎么用,觀眾老爺們心里有答案嗎?)
本著 求知 以及 code less,do more 的精神,我對(duì)剩下的3種組合進(jìn)行了深♂入的研究。
原理其實(shí)很簡(jiǎn)單,Function.prototype.apply(call)其實(shí)就是一個(gè)函數(shù),將視為一個(gè)整體,記作A。原式就可以轉(zhuǎn)換成:A.apply(參數(shù))或A.call(參數(shù)),然后進(jìn)一步轉(zhuǎn)換,參數(shù)1.A(參數(shù)2),什么參數(shù)、參數(shù)1、參數(shù)2的?
相信大家也看出來(lái)了,這里唯一的難點(diǎn)(?)就是參數(shù)。參數(shù)怎么寫(xiě)呢?
其實(shí)很簡(jiǎn)單,apply就傳數(shù)組,call就傳一個(gè)序列。
apply和call的區(qū)別大家肯定知道,我就不多說(shuō)了。第一個(gè)參數(shù)肯定是fn,這個(gè)沒(méi)跑了。關(guān)鍵就在第二個(gè)參數(shù)上。
第二個(gè)參數(shù),首先它形式上要看后一個(gè)apply/call,如果是apply,我們就傳數(shù)組進(jìn)去,如果是call,就傳一個(gè)序列。然后它的內(nèi)容就要看A了,也就是前一個(gè)apply/call,同理,如果是apply,就傳數(shù)組參數(shù),如果是call,就傳序列參數(shù)。
所以我們可以得出以下結(jié)果:
Function.prototype.apply.apply(fn,[null,newArguments]) Function.prototype.call.call(fn,null,...newArguments]) Function.prototype.apply.call(fn,null,newArguments]) //上面3式可以實(shí)際上等于 fn.apply(null,newArguments) fn.call(null,...newArguments) //...為擴(kuò)展運(yùn)算符,...[arr] = arr[0],arr[1],...arr[n] fn.apply(null,newArguments)
繞了一大圈,又回來(lái)了~ :)
而上面的Function.prototype.call.apply也可以改寫(xiě)成:
Function.prototype.call.apply(fn,[null,...newArguments])
從而減少了對(duì)數(shù)組newArguments的操作。
寫(xiě)在最后第一次寫(xiě)文章(水貼),十分緊張,刪了改,改完了刪,總覺(jué)得寫(xiě)的不好、十分啰嗦。
可能會(huì)有人覺(jué)得毫無(wú)意義,但我覺(jué)得這個(gè)倒是可以作為一道面試題。
請(qǐng)?jiān)谔顚?xiě)空白內(nèi)容使等式成立: fn.apply(null,args) = Function.prototype.apply.apply(_____)
如果真的有人遇到,請(qǐng)回來(lái)點(diǎn)贊^ ^
也希望此文能多少幫助到前端新人,大家一起學(xué)習(xí),進(jìn)步!
哪里要是寫(xiě)不好可以直說(shuō)!幫助我進(jìn)步。謝謝!
不廢話了,
完。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/84119.html
摘要:以下是對(duì)史密斯先生有兩個(gè)孩子的可能情況進(jìn)行描述,其中函數(shù)隨機(jī)返回或的概率均為用于模擬現(xiàn)實(shí)中生男孩女孩的概率各一半。 ??無(wú)意在維基看到了一個(gè)關(guān)于概率悖論的討論Boy or Girl paradox。有爭(zhēng)議的的題目如下:??史密斯先生有兩個(gè)孩子,至少其中之一是男孩,請(qǐng)問(wèn)兩個(gè)孩子都是男孩的可能性有多大???原文如下:??Mr. Smith has two children. At leas...
摘要:以下是對(duì)史密斯先生有兩個(gè)孩子的可能情況進(jìn)行描述,其中函數(shù)隨機(jī)返回或的概率均為用于模擬現(xiàn)實(shí)中生男孩女孩的概率各一半。 ??無(wú)意在維基看到了一個(gè)關(guān)于概率悖論的討論Boy or Girl paradox。有爭(zhēng)議的的題目如下:??史密斯先生有兩個(gè)孩子,至少其中之一是男孩,請(qǐng)問(wèn)兩個(gè)孩子都是男孩的可能性有多大???原文如下:??Mr. Smith has two children. At leas...
摘要:補(bǔ)充我弄明白了上面的問(wèn)題,重點(diǎn)在于函數(shù)的作用域,函數(shù)中定義的變量之前我說(shuō)沒(méi)用,為什么沒(méi)用是因?yàn)楹瘮?shù)是定義在函數(shù)下的,所以的作用域鏈?zhǔn)沁@樣的因?yàn)楹瘮?shù)是這樣定義的,所以函數(shù)定義了變量,所以中的賦值給了函數(shù)的參數(shù)。 在阮一峰老師的微博上看到這樣一道題: javascriptfunction a(x, y) { y = function(){ x = 2; }...
摘要:忍者秘籍一書(shū)中,對(duì)于柯里化的定義如下在一個(gè)函數(shù)中首先填充幾個(gè)參數(shù)然后再返回一個(gè)新函數(shù)的技術(shù)稱(chēng)為柯里化。回到我們的題目本身,其實(shí)根據(jù)測(cè)試用例我們可以發(fā)現(xiàn),函數(shù)的要求就是接受單一函數(shù),例如但是與柯里化不同之處在于,柯里化返回的一個(gè)新函數(shù)。 歡迎大家再一次來(lái)到我的文章專(zhuān)欄:從面試題中我們能學(xué)到什么,各位同行小伙伴是否已經(jīng)開(kāi)始了悠閑的春節(jié)假期呢?在這里提前祝大家雞年大吉吧~哈哈,之前有人說(shuō)...
摘要:最后畫(huà)幾張粗糙的圖,簡(jiǎn)單描述一下這個(gè)執(zhí)行的過(guò)程因?yàn)槭擎準(zhǔn)秸{(diào)用,所以在鏈上的都會(huì)入棧然后執(zhí)行,額,執(zhí)行棧少畫(huà)了和。。。 前言:昨天在群里討(jin)論(chui)技(niu)術(shù)(pi),有位老鐵發(fā)了一道他面的某公司面試題,順手保存了。今早花了一點(diǎn)時(shí)間把這題做了出來(lái),發(fā)現(xiàn)挺有意思的,決定在今天認(rèn)真工(hua)作(shui)前,與大家分享我的解題方案和思考過(guò)程。 題目如下(可以自己先思考一會(huì)...
閱讀 2310·2021-11-22 12:01
閱讀 1983·2021-11-12 10:34
閱讀 4509·2021-09-22 15:47
閱讀 2827·2019-08-30 15:56
閱讀 2861·2019-08-30 15:53
閱讀 2398·2019-08-30 13:53
閱讀 3371·2019-08-29 15:35
閱讀 3119·2019-08-29 12:27