4

I think one good way of self-documenting code (wikipedia page) is to have it enclosed in a named block.

For a long piece of code which is only used once and the purpose is not immediately obvious, instead of using comments, one could put it in a named IIFE1 (different variations):

(function functionName() {
  // ...
})();

The function names the code, immediately invokes it and is locally scoped.

That seems good to me but for aesthetics reasons I would like to use an arrow function expression instead.

Unnamed "anonymous" IIAFE2:

(() => {
  // ...
})();

Is there a way to create a named IIAFE?

The following attempt throws a SyntaxError:

(const functionName = () => {
  // ...
})();

Uncaught SyntaxError: Unexpected token 'const'


1 IIFE - immediately invoked function expression
2 IIAFE - immediately invoked arrow function expression

user7393973
  • 2,270
  • 1
  • 20
  • 58
  • 1
    Does this answer your question? [How do I write a named arrow function in ES2015?](https://stackoverflow.com/questions/27977525/how-do-i-write-a-named-arrow-function-in-es2015) Especially the part about `fact` and the part that says *You have to break it into two expressions (I'd argue you should do that anyway)* – Wyck Feb 13 '20 at 14:29
  • @Wyck I just found about labels in [this page](https://esdiscuss.org/topic/iiafes) which seems really good as well. – user7393973 Feb 13 '20 at 15:17

1 Answers1

1

To address the question of self-documenting the code, the solutions below using comments are probably more appropriate.

Solution 1:

{ // explanation of purpose of this block of code
  // locally scoped code
}

Solution 2:

(() => { // explanation
  // code
})();

Solution 3:

// explanation of code below
// code
// optional end of code mark

Solution 4:

(function functionName() {
  // code
})();

As to answer if it is possible to have a named IIAFE:

Without the const statement it declares a named IIAFE to the global scope:

(functionName = () => {
  // ...
})();

Which could be declared to the local scope this way:

let functionName;
(functionName = () => {
  // ...
})();

The following is not exactly immediately invoked but could be used:

const functionName = () => {
  // ...
};
functionName();

Enclosing it inside an anonymous IIAFE could be a workaround, though probably overcomplicated:

(() => {
  const functionName = () => {
    // ...
  };
  functionName();
})();
user7393973
  • 2,270
  • 1
  • 20
  • 58
  • 2
    That last one is just an anonymous IIAFE, and then the *return value* of the function is assigned to a const. The anonymous function does not get assigned to `functionName`. – Nicholas Tower Feb 13 '20 at 13:13
  • @NicholasTower You're correct. It does seem to fit for the purpose explained in the question but if you believe it should be removed or explained feel free to edit the answer, it's community wiki. – user7393973 Feb 13 '20 at 13:16
  • `It does seem to fit for the purpose explained in the question` The question was about making a named iife. It doesn't do so. It makes a named return value. Self documenting code is fine and all, but anyone who understands the code will be confused why something that isn't a function is being called a function. – Nicholas Tower Feb 13 '20 at 13:17
  • @NicholasTower Is the added solution (`let functionName; (functionName = () => { /* ... */ })();`) a locally scoped named IIAFE? – user7393973 Feb 13 '20 at 13:32
  • 1
    That last one is patently wrong and should be deleted before it causes confusion. Especially since it's assigning to a variable called `functionName`. Which will be neither the name of the function, nor the function object. It will just contain the result of the function call. – Wyck Feb 13 '20 at 13:39
  • @Wyck I removed it. – user7393973 Feb 13 '20 at 13:43
  • 1
    Isn't it easier to just write a simple comment at the beginning of the function if you think it's needed…?! – deceze Feb 13 '20 at 13:46
  • @deceze Probably, but in my thought process one thing lead to another which made me curious if it was possible. – user7393973 Feb 13 '20 at 13:52
  • Well, the appropriate answer there is: *No*, use a named IIFE or a comment… – deceze Feb 13 '20 at 13:53
  • I think one of the main uses of an IIFE is that you *do not want to pollute the namespace*. Which makes all your other solutions unsuitable… – deceze Feb 13 '20 at 14:05