访问匿名函数中的对象值

时间:2014-08-24 22:31:18

标签: javascript function this anonymous

我有一个跟踪某个值的对象(Thing),以及一组条件:

var Thing = function(currentValue) {
    this.currentValue = currentValue;
    this.conditions = [];
};

条件可以添加到此列表中:

Thing.prototype.addCondition = function(condition) {
    this.conditions.push(condition);
}

我希望条件采取某种功能的形式,以便我可以做到

thing.addCondition(thing.exampleCondition(valueToCheckFor));

并且可以通过

检查这些条件
Thing.prototype.evaluateConditions = function() {
    this.conditions.forEach(function(condition) {
        if (condition()) {
            //Do something
        }
    });
};

目前我有一个这样的条件函数:

Thing.prototype.exampleCondition = function(value) {
    return function() {
        return this.currentValue === value;
    };
};

这显然不起作用 - 在匿名函数中未定义this.currentValue。我的问题是我需要传递给exampleCondition的值在调用evaluateConditions()时根据currentValue的值进行评估 - 因此我不能

Thing.prototype.exampleCondition = function(value) {
    var c = this.currentValue;
    return function() {
        return c === value;
    };
};

我是一个javascript noob,但希望你这些才华横溢的人能指出我正确的方向。

2 个答案:

答案 0 :(得分:1)

在javascript中,每个函数总是根据上下文进行评估,上下文定义了 this 的值。

在调用函数时,可以显式或隐式设置函数的上下文。要隐式设置上下文,您必须调用这样的函数:

//z will be the context, in other words, inside method: this = z
a.b.c.d...z.method();

为了显式设置上下文,您可以使用的Function对象原型中有两个函数:apply and call。这两个与每个浏览器兼容,因此您不会遇到任何问题。问题在于,使用这两个,您每次调用函数时都会设置上下文,因此如果直接使用它,它将无法帮助您解决问题。

每次调用时,都必须定义一个始终根据相同的上下文进行求值的函数。为此你可以使用在Function对象原型中定义的bind函数,问题是它与旧浏览器不兼容,因为它是ECMA-262第5版的最新版本。然而,解决方案可以将每个条件函数绑定到addCondition函数中的对象:

Thing.prototype.exampleCondition = function(value) {
    return function() {
        return this.currentValue === value;
    };
};

Thing.prototype.addCondition = function(condition) {
    //The bind function will return a function that will always execute with your object as context
    this.conditions.push(condition.bind(this));
}

对于浏览器兼容性问题,您可以try this code。将它放在脚本的开头,您可以确定每个浏览器都有绑定功能。

另一种可能的解决方案可能是:

Thing.prototype.exampleCondition = function(value) {
    var self = this;
    return function() {
        return self.currentValue === value;
    };
};

问题是,在这种情况下,您没有使用上下文,您在返回的函数内忽略它。您可以使用范围中定义的某个变量替换它,而不是使用上下文。为此,您将强制定义为条件函数的每个函数执行该小技巧。我认为第一种解决方案更好。

答案 1 :(得分:0)

问题是this在每个函数内部发生了变化。

然后,在exampleCondition返回的函数内,this将不是您的Thing实例,它将是window非严格模式且{{1}在严格模式下。

因此,你可以做到

undefined

或者,如果您愿意,可以使用ES5 bind

Thing.prototype.exampleCondition = function(value) {
    var that = this;
    return function() {
        return that.currentValue === value;
    };
};