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。)

问题:结果是trueit's false,因为f()in中的函数doMagic不知道变量year是什么,因此它将“1999”与“undefined”进行比较。

如您所见,我知道问题出在哪里,但我想不出任何解决方案。

想法?

问候

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完全取决于函数的调用方式,而不是定义的位置。当调用你传递的函数时valuethis将是全局对象(window浏览器上的 , ),因为代码没有做任何事情来告诉引擎this应该是什么。

所以要解决这个问题,简单的答案是在test函数调用的上下文中创建一个变量,并将其赋值为this; 然后我们使用该变量 ( self) 而不是thisvalue函数内,因为value函数在调用的上下文中关闭test

更多探索(披露:这些都来自我的博客)

于 2012-05-30T12:19:43.740 回答