[JavaScript]IEで名前つき関数オブジェクトの扱いが変
- 2007-11-29
- カテゴリ: Client Side
- タグ: Tips JavaScript IE バグ トラックバック
以前、JavaScriptの名前つき関数オブジェクトのスコープについて調べたことがあった。
僕は名前つき関数オブジェクトを使うのが好きだからよく使う。↓のような感じに。
var fn = function self(i) {
return (i < 10) ? self(++i) : i;
};
↑の関数はまったく意味がない関数だが、名前つき関数オブジェクトを使えば、var fn = の部分に依存せずに再帰処理が書けることがわかる。つまり、関数定義部分だけ適当にコピー&ペーストして使えるということ。
応用
これをちょっと応用して↓みたいなことをやってみた。
var fn = function self() {
return self.staticField;
};
fn.staticField = 'foo';
関数オブジェクトを代入した変数のプロパティとして適当な変数を作って、それを関数オブジェクトの名前で参照する。
さらにちょこっと応用して↓みたいなこともやってみた。
/* use prototype.js */
var fn = Object.extend(
function self() {
return self.staticField;
},
{
staticField: 'foo'
}
);
こうすれば、Object.extendから先の部分をコピー&ペーストして使いまわし放題。
ところが、
応用として紹介した二つのコードは、IE6では動かない。文字列'foo'のかわりにundefinedが返ってきてしまう。
なんでー
調べてみた。
↓のようなコードを書いてみて、名前つき関数オブジェクトの扱いについて調べてみた。
var fn = function self() {
window.alert([
String(fn === self),
String(fn === arguments.callee),
String(self === arguments.callee),
String(fn.staticField),
String(self.staticField),
String(arguments.callee.staticField)
].join('\n'));
};
fn.staticField = 'foo';
fn();
3つの変数(fn, self, arguments.callee)を比較し、さらにそれらの変数から静的変数にアクセスできるかどうかを試した。
ブックマークレットにしておくのでぜひ試してみてもらいたい。
期待する結果は、
true true true foo foo foo
で、FirefoxとOperaは期待通りに動く。
しかしIEは、
false true false foo undefined foo
なんでこうなるんだろう。
やれやれ。
追記
IEでも動くようにしたい場合は、↓のようにすればいいんだよ!
var fn = function() {
var self = arguments.callee;
};
っていうかこっちの方が書き方としては一般的な気がする。
トラックバックURL
- http://liosk.blog103.fc2.com/tb.php/59-c96d2392
1 件のトラックバック
- [JavaScript]名前つきの関数リテラルに関するよくわからない IE の挙動
-
昨日書いた 「IE でも event.currentTarget を使えるようにする」 の記事の後半部分のコードなのですが、IE8 でじっくりと動作を追ってみるとどうも期待通りの動作ではないことがわかりました。 window.attachEvent(”onunload”, (function () { // target._vividcode_el も
- 2009-07-13
- 発信元: vivid memo

