我有一个功能,里面有这个:
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
。)
问题:结果是true
它是false
,因为f()
中的函数doMagic
不知道变量year
是什么,并且所以它将“1999”与“未定义”进行比较。
如你所见,我知道问题所在,但我无法考虑任何解决方案。
想法?
此致
答案 0 :(得分: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
完全取决于函数的调用方式,而不是它定义的位置。在调用您作为value
传递的函数时,this
将成为浏览器上的全局对象(window
),因为代码无法告诉引擎{{1}应该是。
所以要解决它,简单的答案是在调用this
函数的上下文中创建一个变量,并为其赋值test
;然后我们在this
函数中使用该变量(self
)而不是this
,因为value
函数会在调用value
的上下文中关闭。
更多探索(披露:这些都来自我的博客):