JavaScript functions have a length property

Published on in JavaScript

Last updated on

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.