javascript 即時関数の書き方

今回はjavascriptの即時関数を紹介します。


私は最初に即時関数を見たときはその記述方法に驚きました。
しかし、その機能はいたってシンプルで「定義後、即実行」する関数だというだけです。
だんだん見慣れてもきますので、もし即時関数を難しく感じても最初だけなので安心してください。


さっそくですが、実際のコードはこのような感じになります。

即時関数の書き方

(function(){
  //処理...
})();


通常の関数ではロード(定義)された後に呼び出しをされないと実行されませんが、上記のように記載することで「定義後、即実行」という挙動になります。


通常の関数と比較してメリットとよく言われるのが「スコープが閉じている、いわゆるスコープを汚さない」ということです。スコープが閉じていることにより、「他の場所で定義した変数」と同じ名前の変数を定義し使用しても、「他の場所で定義した変数」に影響を与えることはありません。


これは、複数の外部ファイルの読み込みなどで複雑に入り組んでしまい「このアプリでどのような変数を使用しているのか把握できない」ような状況で有用かと思います。


また、即時関数には上記の他にも書き方がありそれぞれ次のように書きます。

引数を指定する場合

引数を指定する場合ではこのように書きます。

(function(val1, val2){
  //処理...
})(1, 2);

関数名を付与する場合

即時関数には、関数名を付与することも出来ます。

(function sokuji_func(){
  //処理...
})();

以上、即時関数の記載方法でした。

追加実験

即時関数には関数名を付与できることを利用して関数定義した場所以外から呼び出せるのか次のコードを書いて試してみました。
結果として、下記のようなエラーが起きてしまい期待していた挙動にはなりませんでした。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
window.onload = function(){
  var sokuji = (function(arg){
    var $p = document.getElementById("p_sokuji");
    $p.style.color = arg;
  })("red");

  var $b = document.getElementById("b_sokuji");
  $b.onclick = function(){
	  sokuji("blue");
  }
}
</script>
</head>
<body>
<p id="p_sokuji">Hello Sokuji Function</p>
<button id="b_sokuji">テスト</button>
</body>
</html>

このようなエラーです。
f:id:somegoro:20170522003943p:plain

ううむ、即時関数を呼び出すにはどのようにしたら良いのでしょうか。
引数なしだったらいけそうな気もします。再度、色々なアプローチで実験してみようと思います。


☆彡追記
この記事について助け舟を出していただきました。 id:KazmaArakaki様、ありがとうございます。とても丁寧な説明でわかりやすかったです。
kazmaarakaki.hatenablog.com

ということで、上記追加実験のエラーについて解決することが出来ました。即時関数は名前をつけても基本的には呼び出すことは出来ません、その事実は引数なしでも変わりません。しかし唯一、即時関数の中からなら呼び出すことが出来るのです。こういった呼び出し方は「再帰」なんて呼びますよね。それでは実際にソースコードを書いていきます。

文字色をランダムに換える関数

var sokuji = (function(arg){
  // 0~4までの数をランダムで取得
  var ran = Math.floor( Math.random() * 5 );
  // 文字の色を設定
  var $p = document.getElementById("p_sokuji");
  
  if($p.style.color == arg[ran]){
    //今の文字色と同じ色ならば、即時関数を再起的に呼び出す
    sokuji(["red", "blue", "green", "pink", "black"]);
  }
  $p.style.color = arg[ran];

})(["red", "blue", "green", "pink", "black"]);


上記のように即時関数を呼び出すには再帰的に呼び出します。(※動作確認未実施です。これから再追加試験としてやります)


今回の記事は以上です。とても良い勉強になりましたね!