logo Ribbit's works

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

#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 型にキャストされる点に注意してください。