91359

[code]

    (function() { return; }());
    (function() { return; })();
    
[/code]

[JavaScript: The Definitive Guide, 7th
Edition](https://www.oreilly.com/library/view/javascript-the-
definitive/9781491952016/)に，IIFEの例として前者のコードが挙げられていました(簡略化しております)．

しかしながら，[JavaScriptのIIFEを使うユースケース -
Qiita](https://qiita.com/snamiki1212/items/37152d0066c57eb60796#%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB%E9%A0%98%E5%9F%9F%E3%82%92%E6%B1%9A%E3%81%97%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E3%82%B1%E3%83%BC%E3%82%B9)や，[JavascriptのIIFEについて考える
-
torikatsu.dev](https://torikatsu923.hatenablog.com/entry/2020/11/19/224003)等では，後者のような記述がされています．

これらの記述方法に何か違いはありますか．


CC BY-SA 4.0
2022-09-28T06:12:21.860
91348
2022-09-30T07:00:05.473
51374
question
javascript
JSの即時関数実行式において，()の位置が変わると挙動にどう影響するか．


[What is the (function() { } )() construct in JavaScript? - Stack
Overflow](https://stackoverflow.com/questions/8228281/what-is-the-function-
construct-in-javascript#comment10893497_8228281) からリンクされている[Immediately-
Invoked Function Expression
(IIFE)](https://benalman.com/news/2010/11/immediately-invoked-function-
expression/)
というアーティクルや、[Wikipedia](https://en.wikipedia.org/wiki/Immediately_invoked_function_expression)の解説及び参照リンク先が参考になるのでは、と思いました。

上記リンク先を見ていただくのが正確かと思いますが、私の理解を以下に記載してみます。

関数を即時実行しているわかりやすい例として次のようなものが挙げられます:  

[code]

    var i = function(){ return 10; }();
    console.log(i)
[/code]

ここで、戻り値が不要なので代入を省略して次のように書こう、とするとシンタックスエラーになります:  

[code]

    function(){ return 10; }();
[/code]

これは、`function`キーワードが最初の例では[関数式](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/function)とみなされますが、次の例では[関数宣言](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/function)とみなされてしまっているためです。  
関数式とみなされるようにするためには(冒頭リンク先にある通り)いくつか方法がありますが、典型的なものとしては、最初の例の右辺全体をカッコで囲ってしまう方法

[code]

    // var i = (function(){ return 10; }());
    // 戻り値は不要なので
    (function(){ return 10; }());
[/code]

の他、関数式の部分だけカッコで囲っても問題を回避できます。

[code]

    (function(){ return 10; })();
[/code]

つまり、質問の回答としては **違いは無い** 、ということになります。

* * *

(追記)  
書籍 [JavaScriptテクニックバイブル](https://gihyo.jp/book/2012/978-4-7741-5243-1) ではまさに
"「(function(){}())」と「(function(){})()」の違い" というセクションがありました(p.142, 4-12
グローバルスコープの汚染を防ぐ)。

ここでは前者は1段階の実行

>   * 式としての「function(){}」を "Function Calls" で呼び出し、 "The Group Operator"
> によって評価した値を返す
>

、後者は2段階の実行

>   * "The Grouping Operator" で「function(){}」を式として認識させ、
>   * "Function Calls" でその評価結果である関数を実行する
>

であると説明し、このため極わずかだが前者の方が実行コストは低い、としています。  
(ただ、本当に差異があるとして、一般的にそれを理由として "The Grouping Operator"
の使用を避けるような方針は採らないのでは、と個人的には考えます)

また、[JSLint](https://www.jslint.com/) は `(function(){})()`
の書式に対して警告を出す([参考](http://linterrors.com/js/do-not-wrap-function-literals-in-
parens))ということも同節で触れられていました。

* * *

どちらの書き方が望ましいか、という点については、2010年に書かれた[こちらの記事](https://benalman.com/news/2010/11/immediately-
invoked-function-expression/#iife)では

>
[code]

>       (function(){ /* code */ }()); // Crockford recommends this one
>       (function(){ /* code */ })(); // But this one works just as well
>  
[/code]

とありますが(*1)、WikipediaからリンクされているES6時代に書かれた[こちらの記事](https://exploringjs.com/es6/ch_arrow-
functions.html#_parenthesizing-arrow-function-with-block-bodies)では

> (前略)
[code]

>     (function () {
>         ···
>     }());
>  
[/code]

>
> Or just around the function expression:
[code]

>     (function () {
>         ···
>     })();
>  
[/code]

>
> Given how arrow functions work, the latter way of parenthesizing should be
> preferred from now on.

とあります。

*1) おそらく Douglas Crockford 氏の著書 [JavaScript: The Good Parts](https://www.oreilly.co.jp/books/9784873113913/) にそういう記述があるのではないかなと想像します([参考](https://www.publickey1.jp/blog/13/javascript_douglas_crockfordqcon_tokyo_2013_1.html))。


CC BY-SA 4.0
2022-09-28T13:02:55.283
91359
2022-09-30T07:00:05.473
2022-09-30T07:00:05.473
2808
2808
91348
answer


違いは無いです。ただし、アロー関数を用いる場合は、後者の記述しか使えません。

[code]

    // おそらく現時点で最短の即時実行関数
    (_=>{ /*コード*/ })()
    
[/code]

### 根拠

[AST
Explorer](https://astexplorer.net/#/gist/694b70ca29e7b3639e6bd1d515b67226/6afec204a6b2f4f828dfb73ba61ec8de85dc0984)
などで見てみると、殆どのパーサーで同じ AST
になっています。当然、これらのパーサーを使うコード生成ツールにかけると、どちらの記述も同じコードに変換されます。

  * [Acorn + Astring](https://david.bonnet.cc/astring/demo/#%28function%28%29%20%7B%20return;%20%7D%28%29%29;%0A%0A%28function%28%29%20%7B%20return;%20%7D%29%28%29;)
  * [Babel](https://babeljs.io/repl#?browsers=defaults&build=&builtIns=false&corejs=3.21&spec=false&loose=false&code_lz=BQMwrgdgxgLglgewsAlAAgN5oE4FMZjYQDcaAvqisQFDWiSyLLpZ4FGlkqrFA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=env&prettier=false&targets=&version=7.19.3&externalPlugins=&assumptions=%7B%7D)

上の2つのコード生成ツールでは、どちらの記述も

[code]

    (function () {
      return;
    })();
    
[/code]

となりました。また、古めの書籍ですが『開眼！ JavaScript』には「同じ結果を得られる」と書かれています。

### 余談: グループ化演算子（丸括弧）を使う理由

質問のリンク先の記事に、

> グループ化演算子は静的なスコープをもっているようです。  
>  ...  
>  名前空間を切り分ける目的でグループ化演算子が用いられていると考えられます。

とあります。これが正しいとすると、引数に渡す式が有った場合は、2つの記述には違いが有ることになります。

しかし、これは誤りです。関数自体がスコープを持ちますので、グループ化演算子で囲まなくとも同じ結果となります。グループ化演算子はスコープを作りません。グループ化演算子を使うのは、単項演算子（`!`
や `~`）を付ける方法と比べると、呪文めいておらず、多少は意図が解り易いからではないかと思います。


CC BY-SA 4.0
2022-09-28T13:27:22.680
91361
2022-09-28T13:27:22.680
3054
91348
answer