1

If possible, what is the simplest way to return a named arrow function?

const add = a => b => b + a
const add5 => add(5)

add.name == 'add' // true
add5.name == '' // true, but I would like it to be 'add5'

So, as one can see the in example above, the returned arrow function is anonymous and I would like it to be named (ideally based on the 'parent' function and the 'parameter' a) — which is useful i.e. for debugging.

marco alves
  • 1,707
  • 2
  • 18
  • 28
  • 2
    your add5 line isn't valid syntax. – Brandon Oct 24 '17 at 20:39
  • 1
    Good question. AFAIK there is no simple way without losing the concise arrow syntax. For this reason I am currently building a run-time type system, which you can plug in during the development stage. It's based on ES6 `Proxy`s and one of its properties is the possibility to give sequences of anonymous arrow functions a name. So a way is to do it with proxys. –  Oct 24 '17 at 20:45
  • 1
    If you want to incorporate the function argument into the function name, you'll have to use `eval`. Are you sure this is worth it? – Thomas Oct 24 '17 at 20:55
  • Why not just use a named function expression instead of an arrow function? – Bergi Oct 24 '17 at 21:41
  • @bergi why is it marked as duplicate? This is about a **returned** arrow function – marco alves Oct 25 '17 at 06:17
  • @marcoalves Does that matter? Write a named arrow function, then return it. – Bergi Oct 25 '17 at 12:11
  • @Bergi as you can see by the answers, not as straightforward — but maybe it is because it's really about **return dynamically named** arrow functions – marco alves Oct 25 '17 at 14:36
  • @marcoalves Ah, that wasn't exactly clear. However, see the possible duplicates [Dynamic function name in javascript](https://stackoverflow.com/q/5905492/1048572) and [Is there any non-eval way to create a function with a runtime-determined name?](https://stackoverflow.com/q/9479046/1048572) for that :-) – Bergi Oct 25 '17 at 18:00

3 Answers3

3

You can do this:

const add = a => (({[`add${a}`]: b => b + a})[`add${a}`]);
const add5 = add(5);

console.log(add5.name);

How it works: define a local object and assign the arrow method as a member with your desired name:

const add = a => {
  const o = {
    [`add${a}`]: b => b + a
  };
  return o[`add${a}`];
};
Brandon
  • 38,310
  • 8
  • 82
  • 87
  • 3
    I believe the OP wants the function named like the variable, and not according to the passed number (*but that is just what i understood*). – Gabriele Petrioli Oct 24 '17 at 20:50
  • @Brandon Is there any when to not to hardwire the *add* in `add${a}` an linked to the *add* in `const add`? – marco alves Oct 25 '17 at 06:41
0

This isn't exactly the same, but:

const add = a => b => a + b;
const add5 = (...a) => add(5)(...a);

console.log(add5(100));  // => 105
console.log(add5.name);  // => 'add5'
div{min-height:100%}
Jordan Running
  • 102,619
  • 17
  • 182
  • 182
0

This example demonstrates how arrow function names are assigned, and this behaviour cannot be changed. Arrow function name is equal to the name of a variable or object property it was assigned to.

name is non-writable property but is configurable in most implementations, including evergreen browsers, so it's safe to use for debugging purposes:

function namedArrow(name, fn) {
  Object.defineProperty(fn, 'name', { enumerable: false, value: name });
  return fn;
}

const foo = namedArrow('foo!', () => { throw new Error });
foo();

It outputs:

[foo]

For debugging purposes displayName can be used also, which is supposed to play same role and is supported by some debuggers and browser debugger tools, notably Firefox and Chrome:

function namedArrow(name, fn) {
  fn.displayName = name;
  return fn;
}

It results in similar output, yet it doesn't play well with Error call stack:

foo

Estus Flask
  • 206,104
  • 70
  • 425
  • 565