[JavaScript]IEで名前つき関数オブジェクトの扱いが変

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[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

トラックバック

[JavaScript]名前つきの関数リテラルに関するよくわからない IE の挙動
昨日書いた 「IE でも event.currentTarget を使えるようにする」 の記事の後半部分のコードなのですが、IE8 でじっくりと動作を追ってみるとどうも期待通りの動作ではないことがわかりました。 window.attachEvent(”onunload”, (function () { // target._vividcode_el も
  • 2009-07-13
  • 発信元: vivid memo

コメント

コメントの投稿

お名前
コメント
編集キー
 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。