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