即時実行関数式
Immediately Invoked Function Expression; 即時実行関数式
JavaScript は何も考えずに変数や関数を定義すると、グローバルオブジェクトにその変数や関数を配置されてしまう。
このため、複数のプログラムを混ぜて利用すると衝突することがある。
これを避けるために、関数スコープ内で変数や関数を宣言して、即時実行するという手法が編み出された。
window.onload を使ってしまうと、上書きになってしまうので、片方しか実行されなくなってしまう。このため、addEventListener で複数定義できるようになった。(これは即時実行とは別件)
さらに、関数が実行されたときに識別子の状態を取り込むか、関数が定義されたときの識別子の状態を取り込むか、の違いがある。(通常の関数とアロー関数との違い)
他の応用もある。特に現在はトップレベルawait ができない場合に、即時実行関数式を使う。
code:a.js
var x = 1;
function showX() {
alert("x is " + x + " in a.js");
}
// window.onload = function () {
window.addEventListener("load", function () {
showX();
}
code:b.js
var x = 2;
function showX() {
alert("x is " + x + " in b.js");
}
// window.onload = function () {
window.addEventListener("load", function () {
showX();
}
code:html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>conflict_global</title>
<script src="a.js"></script>
<script src="b.js"></script>
</head>
<body>
<h1>conflict_global</h1>
</body>
</html>
この場合、x is 2 in b.js というアラートダイアログが2回出てきてしまう。
これを安全に分けるには、関数スコープでくるんでやればよい。
code:a.js
(function() {
var x = 1;
function showX() {
alert("x is " + x + " in a.js");
}
// window.onload = function () {
window.addEventListener("load", function () {
showX();
}
})();
code:b.js
(function() {
var x = 2;
function showX() {
alert("x is " + x + " in b.js");
}
// window.onload = function () {
window.addEventListener("load", function () {
showX();
}
})();
このままだと逆にまったく外から見えなくなるので、グローバルオブジェクトにアプリケーションのオブジェクトを追加する方法が使われる。
code:mymodule.js
(function(global) {
global.mymodule = global.mymodule || {};
global.mymodule.myfunc = function() {
//
}
})();