3

I have an IIFE that works, but when I rewrite it using an arrow function, it does not work!

1.- This one works fine:

let j = 3;

(function (n) {
  while (n--)
    console.log("n only", n);
}(j));

2.- This one doesn't work!:

((n) => {
  while (n--)
    console.log("n only", n);
}(j));

3.- I have already tested the next version which works too:

((n) => {
  while (n--)
    console.log("n only", n);
})(j);

But I really want to understant why the version on (2) does not work.

fender0ne
  • 281
  • 4
  • 13

3 Answers3

4

This is how the language defined it. As mdn states:

Although the arrow in an arrow function is not an operator, arrow functions have special parsing rules that interact differently with operator precedence compared to regular functions.

It continues to give another example, but the principle is the same:

let callback;

callback = callback || function() {}; // ok

callback = callback || () => {};
// SyntaxError: invalid arrow-function arguments

callback = callback || (() => {});    // ok

Although Crockford expressed a preference for putting the closing parenthesis of an IIFE at the very end (after the arguments), I personally find it more intuitive to put it at the same place as where it is required for arrow functions (after the closing brace, before the arguments).

The reason is that the purpose of the parentheses is to turn a function into a function expression and so the arguments really aren't significant in that conversion. So this seems just more to the point:

(function (n) => {
  while (n--)
    console.log("n only", n);
})(j);
trincot
  • 317,000
  • 35
  • 244
  • 286
  • I also prefer using parenthesis enclosing the functions before the arguments, gives more sense from a mathematical point of view. If I had followed this preference from the beginning I would never have encountered this problem. – fender0ne Mar 23 '19 at 09:55
1

What is and what isn't valid syntax is determined by the language grammar.

A CallExpression is defined as

MemberExpression Arguments

But an ArrowFunction is not a MemberExpression, it's an AssignmentExpression.

Why that's the case would be a question for the TC39 committee.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • The grammar for arrow function compared to function looks a little messy. The documentation on mdn says that "[...] the arrow in an arrow function is not an operator", and at the same time, an arrow function is an AssignmentExpression!!?? – fender0ne Mar 23 '19 at 09:46
  • That’s actually OK. Don’t confuse “AssignmentExpression” with an actual assignment. It’s just a non-terminal symbol that describes rules about the language. Every expression is basically an “AssingmentExpression”. If you think of the grammar describing a tree, AssignmentExpression sits almost at the top. `5` is also an AssignmentExpression. – Felix Kling Mar 23 '19 at 15:28
-1

Both work, but you made a typo: make sure you write (<function def>)()

let a = 3;

((b) => {
  while(b--) console.log(b);
})(a);

(function(b){
  while(b--) console.log(b);
})(a);
Nino Filiu
  • 16,660
  • 11
  • 54
  • 84
  • 1
    Pretty sure the inconsistency OP is asking about is that the `function` does *not* need to be surrounded in `()`s, while the arrow function *does*. – CertainPerformance Mar 22 '19 at 23:40
  • 2
    I don't think you understood the question. – trincot Mar 22 '19 at 23:40
  • In my defense, the question is a bit unclear... I didn't downvoted, but the content of [this](https://idownvotedbecau.se/itsnotworking/) reflects my reaction to the question – Nino Filiu Mar 22 '19 at 23:53
  • There are many ways to ask a question. In this case, I could ask about the inconsistency that CertainPerformance refers to – fender0ne Mar 23 '19 at 10:09