簡體   English   中英

在匿名函數中訪問對象值

[英]Accessing object values within anonymous function

我有一個跟蹤某些值以及一組條件的對象(事物):

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的值以在調用validateConditions()時對照currentValue的值進行評估-因此我不能做

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

我有點像javascript菜鳥,但希望你們聰明的人可以在這里為我指明正確的方向。

在javascript中,每個函數總是根據上下文進行評估,該上下文定義了this的值。

可以在調用函數時顯式或隱式設置函數的上下文。 為了隱式設置上下文,您必須調用以下函數:

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

為了顯式設置上下文,可以在Function對象的原型中使用兩個函數: apply和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));
}

為了與瀏覽器兼容,您可以嘗試以下代碼 將其放在腳本的開頭,可以確保每個瀏覽器都具有綁定功能。

另一個可能的解決方案可能是:

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

事實是,在這種情況下,您沒有使用上下文,而是在返回的函數中忽略了它。 而不是使用上下文,而是將其替換為范圍中定義的某些變量。 為此,您要強制定義為條件函數的每個函數執行該操作。 我認為第一個解決方案更好。

問題在於, this在每個函數內部都會發生變化。

然后,在exampleCondition返回的函數內部, this將不是您的Thing實例,它將是非嚴格模式下的window ,而在嚴格模式下undefined

因此,您可以

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

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM