Function length property is not to be trusted

This article is a reply to Stefan Judis’s article How the rest operator and default values affect the function length property.

Stefan shows how a function length is computed when it includes a rest parameter or parameters with a default value.

A quick summary:

const fn1 = (a, b) => {};
const fn2 = (a, ...b) => {};
const fn3 = (a, b = 2) => {};
const fn4 = (a = 1, b) => {};

fn1.length; // -> 2
fn2.length; // -> 1
fn3.length; // -> 1
fn4.length; // -> 0

After a parameter with default

The last one, fn4, is the most interesting case and—as Stefan remarks—good to know.

Actually, I would say it is even more interesting. The interpret generally distinguishes between no default value and default value set to undefined; however, it has no effect on the function execution.

const fn1 = (a, b) => {};
const fn5 = (a = undefined, b = undefined) => {};

fn5.length; // -> 0

Surely, fn1 and fn5 behave exactly the same. The only observable difference is the function length.

As per the specs, internally, parameters without default that appear after one with default are ‘considered to be optional with undefined as their default value’.

Isn’t it crazy?

Oh, one more thing, fn4 would throw a syntax error in some older versions of Firefox.

The length can change

This is some surprise. Yet, indeed, the length of a function can change.

const fn1 = (a, b) => {};
fn1.length; // -> 2

// some magic

fn1.length; // -> 3

What could that magic be?

Assigning something to it would be ignored. (Compare to Array.length.)

fn1.length = 3;
fn1.length; // -> 2

The trick is that the length property of a function has the configurable attribute set to true.

Object.defineProperty(fn1, "length", { value: 3 });
fn1.length; // -> 3

We can go even further and make the property writable:

Object.defineProperty(fn1, "length", { writable: true });
fn1.length = 0;
fn1.length; // -> 0

Right. I know. It is weird.

Valid? Totally.

Valid to use? Hopefully not.

See the example in JSBin: http://jsbin.com/lajucu/edit?js,console

It is worth noting that this is possible since ES2015.


This article was cross-posted to Medium, please use discussion there.

Latest posts

  • 2 min read

3 Mistakes That Give Microservices a Bad Name

I’m sad to see that microservices are falling in popularity among architects and developers. Some say they are unnecessarily complex or overengineered. That one needs to learn so many new tools and technologies. That they introduce problems we had already solved. However, many ‘do microservices’ (unintentionally) wrong…

Read More

  • 1 min read

Why Developers Should Stop Using ISO 8601 for Date-Time

When documenting APIs, developers often link to ISO 8601 as the standard for computer-readable date and date-time format. Dates and times (and time zones!) are complicated. There are so many edge cases and pitfalls. I’m sure every developer has a battle story about them. It’s good to delegate that hard work to somebody else. So when an international body that everybody knows and trusts publishes such a standard, it’s no surprise all the API designers start referring to it.

Read More