[英]js - Higher order unary function - why is this needed?
這是它開始的地方:下面的代碼片段無法按預期工作:
['1', '2', '3'].map(parseInt) // [1, NaN, NaN] <- bad output
一個簡單的改變就可以解決它:
['1', '2', '3'].map(a => parseInt(a)) // [ 1, 2, 3 ] <- good output
但是我正在閱讀的這本書有一個不同的補救措施:
創建一個unary
函數,它接受一個函數(在我們的例子中是parseInt
),如果該函數有n
參數,它返回一個只有一個參數的新函數。 這本書是如何做到的:
const unary = (f) => {
return f.length === 1 ? f : (args) => f(args)
}
['1', '2', '3'].map(unary(parseInt)) // [ 1, 2, 3 ] <- good output again!
我的問題是:
unary
函數是如何工作的?任何幫助將非常感激 :)
給未來讀者的注意事項:結帳咖喱
這個一元函數是如何工作的?
函數的length
是它在第一個具有默認值的參數之前擁有多少個聲明的非剩余參數*。 因此, unary
工作原理是查看函數是否聲稱只接受一個參數,如果是,則返回原始函數,如果不是,則創建一個僅使用一個參數調用原始函數的新函數。
此檢查不可靠,我不會使用該版本的unary
。 許多函數根據它們獲得的實際參數的數量來改變它們的行為,即使它們只聲明一個。
任何可以很好地使用此功能(或至少一般來說是此想法)的實際場景?
一個總是做包裝器的版本(不看length
)對於像你的parseInt
一樣的情況可能很方便:你想只用 X 個參數(1,在你的情況下)調用另一個函數,不管提供了多少你的回調。
這種事情在函數式編程中很常見。 如果您一般不進行函數式編程,那么在箭頭函數的這些日子里,它可能沒有多大用處。 但是相當多的人以函數式的方式使用 JavaScript。
* 是的,就是這么復雜。 示例(需要支持 ES2015 [又名“ES6”] 默認參數值和其余參數的瀏覽器):
function a(one) { } function b(one, two) { } function c(one, two, ...rest) {} function d(one, two = 42, ...rest) {} function e(one, two = 42, three) {} console.log(a.length); // 1 console.log(b.length); // 2 console.log(c.length); // 2 console.log(d.length); // 1 console.log(e.length); // 1
這個一元函數是如何工作的?
函數的length
屬性返回函數具有的形式參數的數量*。 unary
函數檢查函數是否有一個形式參數。 如果是這樣,它只返回原始函數。 如果不是,則返回一個新函數,該函數接受單個參數,將其傳遞給f
並返回結果。
任何可以很好地使用此功能(或至少一般來說是此想法)的實際場景?
如示例所示,某些函數會根據傳入參數的數量改變其行為。 通常(例如當您使用.map
),您真的只想傳入一個參數,而unary()
對此有所幫助。
* 或者至少它曾經如此。 隨着 ES6 的發布,它變得更加復雜。 有關詳細信息,請參閱 TJ Crowder 的回答。
在這個一元函數中,fn.length 正在檢查 parseInt 的參數長度,如果 parseInt 只有一個參數,則它照常返回函數。 但在這種情況下,我們在 parseInt 中有 2 個參數,即 parseInt(value ,radix) 所以我們的 fn.length === 1 失敗了。 如果它有 2 個參數,那么它返回一個 parseInt 參數,該參數僅為值。 例如 parseInt(value) 不是 parseInt(value, radix)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.