前言 前端的小伙伴在面試的時候,幾乎都會遇到一道這樣的面試題: add(1)(2)(3)(4)輸出結果為10。在第一次看到這道面試題的時候,很多小伙伴感到了迷茫!借用王寶強在《人在囧途》中的表演:啥啥啥,這寫的都是啥?下麵胡哥為各位小伙伴帶來這道題的揭秘。 一、核心點 基礎函數的變種 函數柯里化 我 ...
前言
前端的小伙伴在面試的時候,幾乎都會遇到一道這樣的面試題: add(1)(2)(3)(4)輸出結果為10。在第一次看到這道面試題的時候,很多小伙伴感到了迷茫!借用王寶強在《人在囧途》中的表演:啥啥啥,這寫的都是啥?下麵胡哥為各位小伙伴帶來這道題的揭秘。
一、核心點-基礎函數的變種-函數柯里化
我們從0開始,一點點兒的觀察。add(1)(2)(3)(4)輸出的值怎麼成為10,很簡單,大家都明白是1+2+3+4的累加。那使用基礎函數是怎麼實現的呢?
function add (a, b, c, d) {
return a + b + c + d
}
add(1, 2, 3, 4) // 10
那如何add(1)(2)(3)(4)如何也輸出10呢?小伙伴接下來可能會想到這樣:
function add (a) {
return function (b) {
return function (c) {
return function (d) {
return a + b + c + d
}
}
}
}
是不是很完美!
但是如果你這麼回答面試官,面試官肯定會立刻懟死你,累加到100怎麼辦?(PS:沒有說10000已經很客氣了)
王老師經典語錄:下麵的是重點,圈起來,一定要考!!
函數柯里化概念: 柯里化(Currying)是把接受多個參數的函數轉變為接受一個單一參數的函數,並且返回接受餘下的參數且返回結果的新函數的技術。
二、函數柯里化解決方案
函數柯里化有兩種不同的場景,一種為函數參數個數定長的函數,另外一種為函數參數個數不定長的函數。
-
函數參數個數定長的柯里化解決方案
// 定長參數 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
-
函數參數個數不定長的柯里化解決方案
問題升級:那這個問題再升級一下,函數的參數個數不確定時,如何實現呢?
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)())
後記
以上就是胡哥今天給大家分享的內容,喜歡的小伙伴記得收藏
、轉發
、點擊右下角按鈕在看
,推薦給更多小伙伴呦,歡迎多多留言交流...
胡哥有話說,一個有技術,有情懷的胡哥!現任京東前端攻城獅一枚。
胡哥有話說,專註於大前端技術領域,分享前端系統架構,框架實現原理,最新最高效的技術實踐!
長按掃碼關註,更帥更漂亮呦!關註胡哥有話說公眾號,可與胡哥繼續深入交流呦!