IE8- は名前付き関数式を関数宣言としても扱う
ECMAScript の 名前付き関数式
ECMAScript には「名前付き関数式」があり、変数に関数式を代入するときに名前をつけることが出来ます。
var hoge = function foo () { alert(foo); // function foo() { ... } alert(foo === hoge); // true };
ここでは "foo" という名前の関数を作りました。関数fooの内部では foo で関数オブジェクトを参照できますが、関数fooの外部では参照できません。
// 関数宣言 function piyo () { alert(piyo); } // 名前付き関数式 var hoge = function foo () { alert(foo); }; piyo(); // 実行できる hoge(); // 実行できる foo(); // ReferenceError: foo is not defined||<
IE8- の名前付き関数式
IE8- では名前付き関数式を関数宣言としても扱うバグがあります。(IE9 で修正済み)
foo(); // 実行できる alert(foo === hoge); // false var hoge = function foo () { alert(foo === hoge); // false };
これは以下のコードとほぼ同じ動作です。
/** * 関数宣言 */ function foo () { alert(foo === hoge); // false } /** * 関数式 (本来は名前をつけますが、IE8- と挙動を合わせるためにあえて匿名関数にしています) */ var hoge = function () { alert(foo === hoge); // false }; foo(); // 実行できる alert(foo === hoge); // false
hoge.toString() の結果が異なる点を除いて、IE8- と Google Chrome 11 で同じ結果を得られます。
IE8- で本来の名前付き関数式の振る舞いにする
名前付き関数式の代わりに関数宣言を関数スコープに閉じこめてあげれば、本来の名前付き関数式とほぼ同じように振る舞います。
var hoge = (function () { function foo () { alert(foo); } return foo; })();