Per the spec:
The fill method takes up to three arguments value, start and end.
NOTE 1 The start and end arguments are optional with default values of 0 and the length of the this object. If start is negative, it is treated as length+start where length is the length of the array. If end is negative, it is treated as length+end.
(https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.fill)
It is not specified whether the value argument is required or optional.
Google's Closure Compiler treats the first argument as required, but the following code works in Chrome v 71.0.3578.98, Firefox v 64.0, and Opera 60. (I haven't tested other browsers.)
Array(10).fill().map((x, i = 0) => i++) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Array.prototype.fill() doesn't support passing an iterator, but this does the equivalent. In all three browsers, the array passed to map consists of 10 undefined values. For all three browsers, if you skip .fill(), then the array passed to .map() is different, both passing and returning [empty 脳 10] to/from .map(). If you include .fill(), however, you get the expected [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].
The actual values of the array being passed to map() don't matter, so while you could populate it with something other than undefined, that value is a throwaway, so there's no actual need to do so...
Array(10).fill('unused array filler').map((x, i = 0) => i++) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
... and thus the first argument could be seen to indeed be optional.
But is Array.prototype.fill() with zero arguments valid per the spec, or is this a bug in all three implementations?
It's conceptually required, which is why the Array.prototype.fill.length === 1. However, if you omit it, it'll just be undefined.
Every function can always be called with any number of arguments in the language - whether a "required" argument throws when omitted, or has a default value, is a different consideration.
Clause 17 says
Unless otherwise specified in the description of a particular function, if a built-in function or constructor is given fewer arguments than the function is specified to require, the function or constructor shall behave exactly as if it had been given sufficient additional arguments, each such argument being the undefined value.
So
[,,,].fill()
is specified to mean the samething as:
[,,,].fill(undefined)
Most helpful comment
Clause 17 says
So
[,,,].fill()is specified to mean the samething as:
[,,,].fill(undefined)