6

With array destructuring, it's possible to discard leading items by inserting commas without a preceding reference:

const [ , two ] = [ 1, 2 ]

The same isn't true of function signatures — the following code won't parse because the leading comma in the signature is unexpected:

function ditchFirstArgument( , second ){}

Why do I need to provide references for leading parameters in ES6 function expressions?

Barney
  • 16,181
  • 5
  • 62
  • 76
  • 4
    what kind of answer are you looking for? "Because the language doesn't allow it"? If you are asking for reasons for *design decisions*, SO is not a good place for this (because most people here don't work on ECMAScript) – Felix Kling May 14 '16 at 16:17
  • 1
    this would lead to extremely specialized functions with extremely poor reusability. and even worse: the naming of these functions would be a nightmare :D –  May 14 '16 at 16:52
  • Hi Felix, I appreciate most people didn't design Javascript but still thought Stack Overflow would be a good place to get a technical explanation of why the language won't let me do this. I fully expect many SO users not to have an answer — that's fine :) – Barney May 14 '16 at 17:53
  • Ivan, Estus, it's common when writing code for reuse to expose functions which conform to a common interface: this way programmers don't need to know the internal workings of a function, but can expect it to adhere to a certain signature and return output according to a predefined range of expectations. You may want to write a function this way for the same reasons as the destructuring assignment: in this instance, you don't need some parts of the input. Giving them references in this case is just misleading noise. – Barney May 14 '16 at 18:00
  • @Barney I disagree. Extract elements from a keyed/indexed object is a common action. And destructuring is syntactic convenience to solve this job. Extracting parameters to pass only certain arguments isn't the intended use of parameters. This job should be accomplished elsewhere by means which are more suitable. Since your question is opinion based and javascript is a multi paradigm language, different opinions on this issue are fine though, i guess. –  May 14 '16 at 18:53
  • 1
    Why would you define a function that takes a parameter which is ignored? –  May 14 '16 at 19:10
  • @torazaburo because the function is polyadic and bound to a common interface contract. It is common when writing voluminous strictly organised code to organise functions into common polyadic interfaces, that are always called the same way. And yet, in some instances, some of the input will not actually be necessary to the function body. This isn't a problem with trailing arguments, which can simply be omitted. – Barney May 15 '16 at 13:47
  • Congratulations on your robust code organization practices, I'm impressed. In this case, I'd just name the variable `_` as one answer suggests, or `unused`, or some name suggested by your contract with a note that it is unused. –  May 15 '16 at 14:55
  • @torazaburo good ideas. It's not necessarily impressive to create a common interface contract, but a lot of frameworks need it for the sake of author convenience, otherwise you'd have to remember dozens of different signatures. – Barney May 15 '16 at 23:10

3 Answers3

5

Roman's insight from Go is useful but inappropriate to JS where the token _ is a valid reference, conventionally used by the Underscore and later Lodash libraries.

Even if that's acceptable, you'd have to create and avoid dud references for every unused argument, which isn't ideal.

However, it is possible to destructure a function argument into an empty object, which effectively nullifies the parameter without reference.

function take_third( {}, {}, third ){
  return third 
}

EDIT: As Paul points out in the comments, this will throw if any of the skipped parameter values are null or undefined. undefined values can be guarded against with default assignments, but this won't work for null:

function take_third( {} = {}, {} = {}, third ){
  return third 
}
Barney
  • 16,181
  • 5
  • 62
  • 76
4

Why do I need to provide references for leading parameters in ES6 function expressions?

Because otherwise it would be a syntax error. In not just ES6 but any version of the language you cannot elide formal parameters because the spec does not provide for it.

If you really want to do this (but why?), you could write it as

function ditchFirstArgument(...[, second]) {}

or at least you will be able to in some future version of ES; see https://github.com/tc39/ecma262/commit/d322357e6be95bc4bd3e03f5944a736aac55fa50. This already seems to be supported in Chrome. Meanwhile, the best you can do is

function ditchFirstArgument(...args) {
  const [, second] = args;

But why does the spec not allow elision of parameters?

You'd have to ask the people who wrote it, but they may have never even considered it, or if they did, rejected it because it's bug-prone, hardly ever necessary, and can easily be worked around using dummy formal parameters like _.

  • 1
    A caveat is if you use lodash or underscore you might want to use `__` (two underscores) so it doesn't over shadow the global `_` (single underscore) variable. – Sukima Oct 19 '16 at 23:34
3

I believe it's a common pattern to name unused variables with an underscore:

function ditchFirstArgument(_, second) { /* ... */ }

While it would not prevent you from actually using this variable (like in Go), it seems to be a pretty straightforward workaround.