[英]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.