0

I am looking for a way to declare a function without declaring one or more parameters. This would be used in cases where you're implementing a function where you don't care what the value of (for instance) the first argument is.

For example, given this function:

function foo(this_arg_is_unused, important_arg) {
    doSomethingWith(important_arg);
}

Is there some way to declare it more like this?

function foo( , important_arg) {
    doSomethingWith(important_arg);
}

I realize I could easily do this:

function foo() {
    doSomethingWith(arguments[1]);
}

However that starts becoming less readable and it would be more difficult to (for instance) use fn.js to curry the arguments.

I'm currently thinking perhaps I could just use a visual mnemonic to indicate the argument is not used:

function foo(ø, important_arg) {
    doSomethingWith(important_arg);
}

However this may also have readability issues.

Real world example:

The callback function used by jQuery's .each() takes two arguments, the first is either the index or property name in the array/object and the second is the value. To manipulate some div elements you might do something like this:

$($('div').each(function(index, value) {
        console.log(value); // equivalent to doSomething(this)
    }));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Nothing here</div>

Using an arrow function (where using arguments[] is not possible)

$($('div').each((ø, value) => console.log(value)));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Nothing here</div>
Tibrogargan
  • 4,508
  • 3
  • 19
  • 38
  • I don't think JavaScript has any language support for that. A Haskell convention is to use a name that starts with an underscore (e.g. `_index`). – melpomene Oct 18 '16 at 21:02
  • @joews Did you not look at the real world example? Quite often. Most people don't even bother to give the callback for `.each()` arguments since `this` is handy - but you can't use `this` in an arrow function – Tibrogargan Oct 18 '16 at 21:02
  • I always use `_` for the don't care arguments. – Redu Oct 18 '16 at 21:11
  • ...and you can do like `function x(...a){ carryOnWith(...a.slice(1)) }` – Redu Oct 18 '16 at 21:16
  • @Redu `_` would have been my first pick too, except there's at least a couple of libraries that are using it (underscore, gettext) and I'd like to avoid potential issues – Tibrogargan Oct 18 '16 at 21:21

2 Answers2

0

You can't leave empty spaces in function arguments. A placeholder argument works well.

If you don't want to do that, you could write a higher-order function that wraps a function to expect a first, throwaway argument:

function withExtraArg(f, thisValue = null) {
  return (x, ...args) => f.call(thisValue, ...args);
}

And write your function taking a natural number of arguments:

function withExtraArg(f, thisValue = null) {
  return (x, ...args) => f.call(thisValue, ...args);
}

// your function
function log (value) {
  console.log(value)
}

$($('div').each(withExtraArg(log)));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Nothing here</div>
joews
  • 29,767
  • 10
  • 79
  • 91
0

It there a way to leave a function argument undeclared?

No. Just omitting it is a syntax error.

Perhaps I could just use a visual mnemonic to indicate the argument is not used

Yes, that's the right way. The idiomatic name for unused parameters is the underscore _, known from other languages where it has a special meaning (and can even be used multiple times):

function foo(_, important_arg) {

Real world example: the callback function used by jQuery's .each()

Yes, jQuery has messed up the arguments order of the callback, usually the value goes first. In jQuery, the value goes in the zeroeth argument - the this value, so idiomatic jQuery is

$('div').each(function() {
    console.log(this);
});

If you cannot use this for some reason, you will have to use the second parameter; there's no way around this.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I'd like to use `_`, but it would break gettext (which is why I'm leaning towards using the "null"). I'm aware of the jQuery idiom, but it fails in arrow functions. – Tibrogargan Oct 18 '16 at 21:09
  • @Tibrogargan What do you mean by "gettext"? And yes, [you're not supposed to use arrow functions everywhere](http://stackoverflow.com/q/34361379/1048572) - jQuery could be considered broken in that regard, but they'll hardly change it for compatibility reasons (as always in JS). – Bergi Oct 18 '16 at 21:12
  • [gettext](https://www.gnu.org/software/gettext/). There's libraries for it in many languages and many of them (including JS) use `_` as their macro/global/hook – Tibrogargan Oct 18 '16 at 21:24
  • I guess using two underscores (`__`) would work as well if you need to avoid collisions. Or just name it `index` and simply not use it. – Bergi Oct 18 '16 at 21:37
  • either that or use joews answer (which is functionally the same as fn.js:curry()). I'm thinking maybe the [Haskell style] __ / _xyz / _unused might be the easiest, but maybe I'll stick with my ø – Tibrogargan Oct 18 '16 at 21:41
  • @Tibrogargan isn't it more like the inverse of partial application? In that it effectively increases the arity of a function. – joews Oct 18 '16 at 21:50
  • @joews You're right. I shouldn't assume people are telepathic :) functionally the same family. It modifies the arity. – Tibrogargan Oct 18 '16 at 21:53
  • @bergi I really want to just plonk `void` in there in place of any argument I'm not using. – Tibrogargan Oct 18 '16 at 22:00
  • @Tibrogargan Yeah, unfortunately `void` is a keyword… – Bergi Oct 18 '16 at 22:12
  • @joews what you've written is basically the `const` function (if we assume curried functions) – Bergi Oct 18 '16 at 22:13
  • @Bergi that's neat, thanks. I [read about that recently](https://leanpub.com/javascriptallongesix/read) but didn't make the connection. – joews Oct 18 '16 at 22:22