我有两个类似的Javascript“对象”......
var Object2 = new (function() {
this.FetchData = function(callback) {
// do some stuff
callback(data);
};
});
var Object1 = new (function() {
this.DisplayStuff = function() {
};
this.LoadData = function() {
Object2.FetchData(this.OnData);
};
this.OnData = function(data) {
// this == window
this.DisplayStuff(); // doesn't work
};
});
当Object1收到OnData的回调时,“this”的值设置为window。 有什么办法可以解决这个问题,以便OnData里面的“this”的值是Object1的实例而不是窗口?
答案 0 :(得分:5)
框架中常用的一种技术是让调用者决定回调函数的this
上下文应该是什么。所以FetchData
函数看起来像(感谢@Andy告诉我上下文为null或未定义时的默认范围 - 它是全局对象),
this.FetchData = function(callback, context) {
callback.call(context, data);
};
调用FetchData
时,将Object1
作为回调的上下文传递,
Object2.FetchData(this.OnData, this);
另一种选择是使用Function.prototype.bind将OnData
函数与Object1
绑定
Object2.FetchData(this.onData.bind(this));
答案 1 :(得分:3)
这样做的简单方法是在变量中存储 this 的引用,然后使用call()方法:
this.LoadData = function() {
var self = this;
Object2.FetchData(function () { self.OnData.call(self) });
};
如果你这么做很多,你可能要考虑在ECMAScript第5版的函数原型上使用 .bind()方法。可以在不受支持的地方实施此方法:
// From Prototype.js
if (!Function.prototype.bind) { // check if native implementation available
Function.prototype.bind = function(){
var fn = this, args = Array.prototype.slice.call(arguments),
object = args.shift();
return function(){
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
};
};
}
结果函数调用:
this.LoadData = function() {
Object2.FetchData(this.OnData.bind(this));
};
答案 2 :(得分:0)
基本解决方案是使用apply
强制回调上下文。 (或call
。不同之处在于参数的传递方式。数组或“正常”)请参阅MDC以获取文档。
答案 3 :(得分:0)
对于回调,你会被“这个”作为窗口(通常)。但是,您可以向Object1添加一个指向自身的成员(很多时候它会调用'self',即“var self = this;”),然后使用它,即self.DisplayStuff()。
答案 4 :(得分:0)
使用javascript,“这个”的模糊性对我来说真的很烦人。所以我尽可能地避免“这个”。我是这样做的:
var Object2 = (function() { // no need for a "new" keyword any more
var self = {}; // instead of the auto-supplied "this", create my own "self"
self.FetchData = function(callback) {
// do some stuff
callback(data);
};
return self; // don't forget to return "self"
});
var Object1 = (function() {
var self = {}; // instead of the auto-supplied "this", create my own "self"
self.DisplayStuff = function() {
};
self.LoadData = function() {
Object2.FetchData(this.OnData);
};
self.OnData = function(data) {
self.DisplayStuff();
};
return self; // don't forget to return "self"
});
你失去了使用这种技术使用Object.prototype的能力,你失去了使用“instanceof”进行测试的能力,但你永远不必考虑“这个”是什么。