前端經典面試題解密-add(1)(2)(3)(4) == 10到底是個啥?

寫在前面:本期教程算是個經常會遇到的面試題,更多的前端視頻教程也會繼續給大家出,文末有給大家總結有相關的視頻學習教程,大家按需自行學習哈!不全的地方,大家可以留言或私我,我再發。

前端的小夥伴在面試的時候,幾乎都會遇到一道這樣的面試題: add(1)(2)(3)(4)輸出結果為10。在第一次看到這道面試題的時候,很多小夥伴感到了迷茫!借用王寶強在《人在囧途》中的表演:啥啥啥,這寫的都是啥?下面為各位小夥伴帶來這道題的揭秘。



一、核心點-基礎函數的變種-函數柯里化

我們從0開始,一點點兒的觀察。add(1)(2)(3)(4)輸出的值怎麼成為10,很簡單,大家都明白是1+2+3+4的累加。那使用基礎函數是怎麼實現的呢?

<code>function add (a, b, c, d) { return a + b + c + d } add(1, 2, 3, 4) // 10 /<code>

那如何add(1)(2)(3)(4)如何也輸出10呢?小夥伴接下來可能會想到這樣:

<code>function add (a) { return function (b) { return function (c) { return function (d) { return a + b + c + d } } } } /<code>

是不是很完美!

但是如果你這麼回答面試官,面試官肯定會立刻懟死你,累加到100怎麼辦?(PS:沒有說10000已經很客氣了)

你老師經典語錄:下面的是重點,圈起來,一定要考!!

函數柯里化概念: 柯里化(Currying)是把接受多個參數的函數轉變為接受一個單一參數的函數,並且返回接受餘下的參數且返回結果的新函數的技術。

二、函數柯里化解決方案

函數柯里化有兩種不同的場景,一種為函數參數個數定長的函數,另外一種為函數參數個數不定長的函數。

1.函數參數個數定長的柯里化解決方案

<code>// 定長參數 function add (a, b, c, d) { return [ ...arguments ].reduce((a, b) => a + b) } function currying (fn) { let len = fn.length let args = [] return function _c (...newArgs) { // 合併參數 args = [ ...args, ...newArgs ] // 判斷當前參數集合args的長度是否 < 目標函數fn的需求參數長度 if (args.length < len) { // 繼續返回函數 return _c } else { // 返回執行結果 return fn.apply(this, args.slice(0, len)) } } } let addCurry = currying(add) let total = addCurry(1)(2)(3)(4) // 同時支持addCurry(1)(2, 3)(4)該方式調用 console.log(total) // 10 /<code>

2.函數參數個數不定長的柯里化解決方案

問題升級:那這個問題再升級一下,函數的參數個數不確定時,如何實現呢?

<code>function add (...args) { return args.reduce((a, b) => a + b) } function currying (fn) { let args = [] return function _c (...newArgs) { if (newArgs.length) { args = [ ...args, ...newArgs ] return _c } else { return fn.apply(this, args) } } } let addCurry = currying(add) // 注意調用方式的變化 console.log(addCurry(1)(2)(3)(4, 5)()) /<code>

最後:有不清楚的地方,夥伴們可以留言,今天的教程先到這裡,另外給夥伴們些乾貨,可以私下給自己鍍鍍金!