6

considering

function f() { ... }

and another function dosomething expecting a function like f

function dosomething(callback) { ...; callback() } 

that expects f (an example of dosomething can be setTimeout)

calling dosomething and passing f, is there a difference between:

dosomething(f);

and

dosomething(() => f());

is any of these options preferable ?

kofifus
  • 17,260
  • 17
  • 99
  • 173
  • so this will be different in these cases ? – kofifus Apr 19 '16 at 00:37
  • [Yes.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions). Arrow functions don't introduce their own `this` – Mark Reed Apr 19 '16 at 00:43
  • yes but since the arrow function calls f() wouldn't this inside f be the same in both cases ? – kofifus Apr 19 '16 at 00:45
  • yes my question is specifically about this case (for example passing f to setTimeout), so in this case can you answer the question ? is there any difference and is any form preferable ? – kofifus Apr 19 '16 at 00:50
  • 2
    Inside `f`, in this case, `this` would be the same either way. – Mark Reed Apr 19 '16 at 01:05
  • Jonathan I asked a very specific question giving a very specific use case - a function receiving no parameters `f` and a function expecting a function with no parameters such as doSomething or setTimeout. Would it be better to write setTimeout(f,10) or setTimeout(()=>f(), 10) ? is there a difference ? – kofifus Apr 19 '16 at 01:10
  • 1
    `dosomething(f)` passes a reference to *f*, whereas `dosomething(() => f())` passes a function that calls *f*, so effectively `dosomething(function(){f()})`. – RobG Apr 19 '16 at 01:13
  • the only difference is the waste of an extraneous function definition and call. Sure, the arrow function inherits the surrounding `this` - but then all it does is call `f`, which has the default/global one. There is no point in not just doing `dosomething(f)`. – Mark Reed Apr 19 '16 at 01:15
  • Thx Mark, can you please post this as an answer ? – kofifus Apr 19 '16 at 01:26
  • 1
    @MarkReed and the others, this question does not seem to be the same as http://stackoverflow.com/questions/34361379/arrow-function-vs-function-declaration-expressions-are-they-equivalent-exch. – Quentin Roy Apr 19 '16 at 02:42

1 Answers1

4

That the wrapping function (second example) is an arrow function or not does not change a thing here.

However, this wrapping function can be useful to forbid arguments transfer: in the first case, if callback is called with an argument, it will be given to f. Not in the the second case. An alternative could be to restrict the number of transmitted arguments: dosomething((a, b) => f(a, b));.

It can also be used to protect against this injection: in the first case, doSomething can bind f to change its this (callback.bind(whatever)). With a wrapping function (arrow or not), it won't have any effect and f will keep his this (the global context) whatever doSomething does.

Quentin Roy
  • 7,677
  • 2
  • 32
  • 50
  • 3
    Another distinction: arity control. You may be passing a callback function that expects a certain number of arguments (0 in this case), but there's nothing to stop the function you pass the callback to from passing more. The wrapper function means those extra arguments don't make it through to the real callback. For a quicki trivial example of this in action, compare the output of `[1,2,3,4,5].forEach(console.log)` with that of `[1,2,3,4,5].forEach((n) => console.log(n))` in Node. – Mark Reed Apr 19 '16 at 21:18
  • Thanks, I edited my answer. – Quentin Roy Apr 21 '16 at 04:38