此处开始:以下代码段未按预期运作:
['1', '2', '3'].map(parseInt) // [1, NaN, NaN] <- bad output
一个简单的改变可以解决它:
['1', '2', '3'].map(a => parseInt(a)) // [ 1, 2, 3 ] <- good output
但是这篇book我的阅读有不同的补救措施:
创建一个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
功能如何运作?非常感谢任何帮助:)
未来读者注意:结帐currying
答案 0 :(得分:3)
这个一元功能如何运作?
函数的length
是在第一个参数之前具有默认值*的声明的非静止参数的数量。所以unary
通过查看函数是否声明只接受一个参数来工作,如果是这样,则返回原始函数,如果不是,则创建一个只用一个参数调用原始函数的新函数。
此检查不可靠,我不会使用该版本的unary
。许多函数根据它们获得的实际参数数量来改变它们的行为,即使它们只声明了一个。
任何实际情况下,这个功能(或者至少是这个概念)都会有很好的用途吗?
总是做包装器的版本(不看length
)对于像parseInt
一样的情况可能很方便:你想用只有X个参数调用另一个函数(1,in你的情况),无论你的回调提供了多少。
这种事情在functional programming中很常见。如果你不一般都在进行函数式编程,那么可能在箭头函数的这些日子里它没什么用处。但是相当多的人以功能的方式使用JavaScript。
*是的,这很复杂。示例(需要支持ES2015 [aka“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
答案 1 :(得分:2)
这个一元功能如何运作?
函数上的length
属性返回函数具有*的形式参数的数量。 unary
函数检查函数是否有一个正式参数。如果是这样,它只返回原始函数。如果没有,则返回一个新函数,该函数接受一个参数,将其传递给f
,然后返回结果。
任何实际情况下,这个功能(或者至少是这个概念)都会有很好的用途吗?
如示例所示,某些函数会根据传入的参数数量来更改其行为。经常(例如当你使用.map
时),你真的只想传递一个参数,unary()
有助于此。
*或者至少它已经习惯了。随着ES6的发布,它现在变得更加复杂。见T.J.克劳德详细解答。
答案 2 :(得分:1)
在此一元函数中,fn.length正在检查parseInt的参数长度, 如果parseInt仅具有一个参数,则它将照常返回该函数。但是在这种情况下 我们在parseInt中有2个参数是parseInt(value,radix),因此我们的fn.length === 1失败。 如果它有2个参数,则返回带有一个仅是值的参数的parseInt。例如parseInt(value)不是parseInt(value,radix)