2

There was a Function.prototype.arity property purposed for getting number of arguments function expects. Now it is obsolete (since JS 1.4), and the same goal has Function.prototype.length.

But recently I've found an article in the documentation about Array.prototype.reduce method. And it clearly says that the method has property length equal to 1:

The length property of the reduce method is 1.

This exact article has a header with number of arguments, and there are two of them:

Array.prototype.reduce ( callbackfn [ , initialValue ] )

callbackfn and initialValue (optional).

So it is not clear to me, what exactly the purpose of length property.
If it is used to give useful information to developer, then it actually does not.
If it is just a technical automatically-generated property that just indicates number of arguments in function definition, then why don't maintain its consistency?

Parzh from Ukraine
  • 7,999
  • 3
  • 34
  • 65
  • 2
    [ECMAScript 5.1, Section 15.3.5.1, `length`](http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5.1): "_The value of the length property is an integer that indicates the **“typical” number of arguments expected** by the function. However, the language permits the function to be invoked with some other number of arguments._" – Andreas Mar 01 '17 at 12:10
  • `reduce` is expecting one parametter (necessary) and the other is optional so it doesn't count! – ibrahim mahrir Mar 01 '17 at 12:12
  • at least you need a callback function to run reduce. – Nina Scholz Mar 01 '17 at 12:12
  • Side note: The `length` property is a property on individual instances, not a prototype property; [spec](http://www.ecma-international.org/ecma-262/7.0/index.html#sec-function-instances-length). The only reason `Function.prototype` has a `length` property is that `Function.prototype` is a `Function` instance (for historic reasons, mostly). – T.J. Crowder Mar 01 '17 at 12:30

1 Answers1

1

Array.prototype.reduce's length is 1 because the second parameter is optional.*

So it is not clear to me, what exactly the purpose of length property.

To tell the developer how many declared parameters it has prior to the first parameter with a default value (if any) or the rest parameter (if any), whichever is earliest in the parameter list. Or as the spec puts it:

The value of the length property is an integer that indicates the typical number of arguments expected by the function.

The exact algorithm is in the spec's Static Semantics: ExpectedArgumentCount section.

If it is used to give useful information to developer, then it actually does not.

Well, that's a matter of opinion. :-)

When you have a language like JavaScript where functions can only express an expectation but may be called with fewer or more arguments, and particularly when you add the concepts of default parameter values and rest parameters, it's not surprising that the arity of function is a bit of a soft concept.

Some fun examples:

function ex1(a) { }             // length is 1, of course
function ex2(a, b = 42) { }     // length is 1, `b` has a default
function ex3(a, b = 42, c) { }  // length is 1, `b` has a default and
                                // `c` is after `b`
function ex4(a, ...rest) { }    // length is 1 yet again, rest parameter doesn't count

* In ES5, its declaration in JavaScript would be:

function reduce(callback) {
    // ...
}

...and then it would use arguments.length to determine whether you'd supposed an initialValue.

In ES2015+ (aka "ES6"+), it would either still be like that, or be like this:

function reduce(callback, ...args) {
    // ...
}

...and use args.length to see if there was an initial value.

Or possibly like this:

const omitted = {};
function reduce(callback, initialValue = omitted) {
    // ...
}

...and then use initialValue === omitted to know whether you'd supplied an initial value. (The default value of initialValue can't be undefined or null or similar because the function has to branch based on whether the argument was provided [not what its value is]. But we can do that with object identity.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • All of this, except perhaps the rest parameters, is not very intuitive in JavaScript. – Parzh from Ukraine Mar 01 '17 at 12:35
  • @DmitryParzhitsky: Yeah, well, again, it's a matter of opinion. The default parameter values not being counted was surprising to me originally, but one has to remember they were added to the language 20 years after it was first created. TC39 (the committee that manages the language) have a *very* difficult job moving JavaScript forward without breaking things that were written 15 years ago and still get used all over. The common idiom for default parameters before we had them in the language resulted in their not being counted, so I'm guessing that's why they went that way. :-) – T.J. Crowder Mar 01 '17 at 12:42