A bit exotic, but can be useful for currying.
Table of contents
Function.length
The length
property of a function
returns the number of required arguments:
(() => {}).length //=> 0
((a) => {}).length //=> 1
((a, b) => {}).length //=> 2
((a, b, c) => {}).length //=> 3
((a, b, c = 'default') => {}).length //=> 2
((a, ...args) => {}).length //=> 1
((...args) => {}).length //=> 0
I learned this from a tweet by Mikael Ainalem.
See also
Function.length
on MDN.
Trust issues
Robin Pokorny says that
the length
property is not to be trusted
because it can be overridden:
const fn = (a, b) => {}
fn.length //=> 2
Object.defineProperty(fn, 'length', { value: 3 })
fn.length //=> 3
But don't do that. 😄
Example: currying
One practical use of Function.length
is to use it to create a currying function:
const curry = (fn, ...args) =>
fn.length > args.length
? curry.bind(null, fn, ...args)
: fn(...args)
const mul = (a, b, c) => a * b * c
curry(mul, 1, 2, 3) //=> 6
curry(mul, 1, 2)(3) //=> 6
curry(mul, 1)(2, 3) //=> 6
curry(mul, 1)(2)(3) //=> 6
curry(mul)(1, 2, 3) //=> 6
curry(mul)(1, 2)(3) //=> 6
curry(mul)(1)(2, 3) //=> 6
curry(mul)(1)(2)(3) //=> 6
Source of the curry
function:
Babak's reply to Mikael's tweet.