Javascriptの即時関数と、省略記法【先頭の!やカッコの意味】

記事のトップ画像

即時関数とは

即時関数は、記述と同時に実行される関数を指します。
具体例を挙げると、これも

console.log('スクリプトの先頭です。');
(function() {
  console.log('スクリプト実行中。');
})();
console.log('スクリプトの末尾です。');

これも

console.log('スクリプトの先頭です。');
func();
console.log('スクリプトの末尾です。');
function func() {
    console.log('スクリプト実行中。');
}

これも

console.log('スクリプトの先頭です。');
console.log('スクリプト実行中。');
console.log('スクリプトの末尾です。');

上記全て処理の流れは同じです。結果は以下になります。

スクリプトの先頭です。
スクリプト実行中。
スクリプトの末尾です。

すでに存在していた処理の一部を即時関数にしたとしても、処理の流れが変わることはありません。

なぜ必要なのか

変数のスコープを制限し、汚染を防ぐためです。
例えば、以下の処理は全く問題なく実行されます。

var foo = 'スクリプトの途中で定義されました';
console.log('スクリプト実行中。', foo);
console.log('スクリプトの末尾です。', foo);
スクリプトの先頭です。
スクリプト実行中。 スクリプトの途中で定義されました
スクリプトの末尾です。 スクリプトの途中で定義されました

ですが、以下の場合だとエラーとなります。

console.log('スクリプトの先頭です。');
(function() {
    var foo = '即時関数の中で定義されました';
    console.log('スクリプト実行中。', foo);
})();
console.log('スクリプトの末尾です。', foo);
スクリプトの先頭です。
スクリプト実行中。 即時関数の中で定義されました
Uncaught ReferenceError: foo is not defined

即時関数の省略記法

Javascriptの即時関数には、いくつか省略して記述する方法があります。

'use strict';
(function(){
    const foo = 'a';
})();
!function(){
    const foo = 'b';
}();
+function(){
    const foo = 'c';
}();
-function(){
    const foo = 'd';
}();
void function(){
    const foo = 'e';
}();
typeof function(){
    const foo = 'f';
}();

全て有効です。実行結果にエラーは発生しません。
CDNで利用できるJavascriptには、2番目の「!」を使うものをよく見かけるかと思います。

「!」は本来、論理演算子として利用されているものなので、即時関数の返り値がboolean型にキャストされる点に注意してください。