function の文・式、そして即時関数について調べた
こんなコードが会社 Slack にポッと投稿されたのだけど分からないことがあった
!function() { window.dribble = 0; var elem = document.querySelector("body > div.new_identity > ul > li:nth-child(2) > a > div"); elem.addEventListener('mouseover', function() { window.dribble += 1; this.innerText = window.dribble; }); }()
- これ即時関数なんだけど、先頭の
!
はナニ???となった - :@furuk4wa: 僕の知ってる即時関数は
(function () { console.log('hoge') })()
だった
そもそも即時関数として実行するには
- function 式 に
()
をつけるなどして呼び出す- 式な
JavaScript における 式 と 文 の違い
- 参考: 文と式 · JavaScriptの入門書 #jsprimer
- 式
- 自身を評価し、値を返すもの
- 例
1 + 1 // => 1
"a"
- 文
文(Statement)を簡潔に述べると、処理を実行する1ステップが1つの文といえます。 JavaScriptでは、文の末尾にセミコロン(;)を置くことで文と文に区切りを付けます。
関数の 式 と 文
- 参考: JavaScriptのfunction文とfunction式を考えてみる - webアプリの開発日記
- 「文」が
function
キーワードから始まる場合、その function は文となる {
,function
以外から始まる場合、function は式となる
よって
- 前述したコードの
!
は 続く function を式とするためのものである
!function() { window.dribble = 0; var elem = document.querySelector("body > div.new_identity > ul > li:nth-child(2) > a > div"); elem.addEventListener('mouseover', function() { window.dribble += 1; this.innerText = window.dribble; }); }()
- 式であればよいので以下も即時関数として OK(出典: ソーシャルボタンのJavaScriptでfunctionの前に「!」がついている理由 - hogehoge @teramako
!function(){}(); +function(){}(); -function(){}(); ~function(){}(); (function(){}()); // Grouping Operator 0,function(){}(); a=function(){}(); [function(){}()]; // Array Literal new function(){}; // 正確にはCallExpressionではなく、NewExpression だが 1+function(){}(); 0|function(){}(); 0&function(){}(); 0||function(){}(); 1&&function(){}(); ++functtion(){}(); // 実行後エラーがでるけど --functtion(){}(); // 実行後エラーがでるけど void function(){}(); typeof function(){}(); delete function(){}();
アロー関数 ( Arrow function ) の場合
- Arrow function の場合はそうもいかない
- 即時関数として実行するにはグループ化する必要がある
- 参考: ES2015(ES6)新構文:アロー関数(Arrow function)|もっこりJavaScript|ANALOGIC(アナロジック)
通常の関数式の場合、
(function () { / 関数本体 / }());
と書いても
(function () { / 関数本体 / })();
の様に書いてもどちらも即時実行されるのですが、アロー関数の場合は
(() => { / 関数本体 / })();
の様に記述しなければならないようです。
- とのこと :@furuk4wa: