簡體   English   中英

js - 高階一元函數 - 為什么需要這個?

[英]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!

我的問題是:

  1. 這個unary函數是如何工作的?
  2. 任何可以很好地使用此功能(或至少一般來說是此想法)的實際場景?

任何幫助將非常感激 :)


給未來讀者的注意事項:結帳咖喱

這個一元函數是如何工作的?

函數的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM