1

私はその中にこれを含む関数を持っています:

var fobj = function(){};

var my_obj = fobj.extend({
    test: function(){
        this.year = 1999;  
        my_fmagic.doMagic([
            {
                field: 'year', 
                type: 'function', 
                value: function(data_from_doMagic){

                    console.log(data_from_doMagic, this.year);

                    return data_from_doMagic == this.year;
                }
            }
        ]);
    }
});

次に、doMagic関数:

var fmagic = function(){};

var my_fmagic = fmagic.extend({
    doMagic: function( rules ) {
        var data_from_doMagic = 1999;
        _.each(rules, function(rule) { 
            switch(rule.type) {
                case "function":
                    var f = _.wrap(rule.value, function(func){
                        return func( data_from_doMagic );
                    });
                    f();
                    break;
            }
        });
    }
});

アイデアは次のとおりです。「ルール」の配列を渡しdoMagicて、残りを任せます。

期待される結果:test()返される必要がありtrueます (まあ、この例では何も返されません。明らかに、何も返されないためです。ただし、valueルールのフィールドは である必要がありますtrue。)

問題:の関数は変数が何であるかを認識せず、"1999" と "undefined" を比較するため、結果は代わりにtrueitになります。falsef()doMagicyear

ご覧のとおり、問題の場所はわかっていますが、解決策については考えられません。

アイデア?

よろしく

4

1 に答える 1

1

(元の)質問に投稿したコードは、問題を示すフィドルに表示されたコードとは根本的に異なりました。

問題はここにあります:

test: function(){
    this.year = 1999;  // <=== This isn't a variable, as you originally showed
    my_fmagic.doMagic([
        {
            field: 'year', 
            type: 'function', 
            value: function(data_from_doMagic){

                // *** `this` here won't be the same as `this` was above ***

                console.log(data_from_doMagic, this.year);

                return data_from_doMagic == this.year;
            }
        }
    ]);
}

簡単な修正は次のとおりです。

test: function(){
    var self = this;   // <=== Create a variable to close over

    this.year = 1999;

    my_fmagic.doMagic([
        {
            field: 'year', 
            type: 'function', 
            value: function(data_from_doMagic){

                console.log(data_from_doMagic, self.year); // <== And use it here

                return data_from_doMagic == self.year;     // <== And use it here
            }
        }
    ]);
}

更新されたフィドル

これは、JavaScript では、関数が定義されている場所ではなく、関数の呼び出しthis方法によって完全に決定されるためです。として渡す関数を呼び出すと、コードはエンジンに何をすべきかを伝えるために何もしていないため、グローバル オブジェクト (ブラウザでは )になります。valuethiswindowthis

したがって、それを解決するための簡単な答えは、関数呼び出しのコンテキストで変数を作成し、それに;testの値を割り当てることです。次に、関数内ではなくthisその変数 ( ) を使用します。これは、関数が への呼び出しのコンテキストを閉じるためです。selfthisvaluevaluetest

さらに探索する(開示:これらはすべて私のブログからのものです)

于 2012-05-30T12:19:43.740 に答える