Javascript 当该值为空时
我试图为接受回调的函数实现一个简单的队列。我的问题是,在flush方法中,当正在执行的操作是一些长时间运行的事情(在我的例子中是indexedDB调用)时,“this”为null。我以前从未经历过这种行为,所以请告诉我发生了什么 代码如下:Javascript 当该值为空时,javascript,Javascript,我试图为接受回调的函数实现一个简单的队列。我的问题是,在flush方法中,当正在执行的操作是一些长时间运行的事情(在我的例子中是indexedDB调用)时,“this”为null。我以前从未经历过这种行为,所以请告诉我发生了什么 代码如下: var Queue = (function () { function Queue() { }; Queue.prototype.items = []; Queue.prototype.results = []; Q
var Queue = (function () {
function Queue() {
};
Queue.prototype.items = [];
Queue.prototype.results = [];
Queue.prototype.add = function (action) {
this.items.push(action);
};
Queue.prototype.complete = function () { };
Queue.prototype.flush = function () {
var args = Array.prototype.slice.call(arguments);
if (args.length > 0) { this.results.push(args); }
if (this.items.length > 0) {
var action = this.items.shift();
action.call(this);
} else { // Complete, call back multi.
var results = this.results;
this.clear();
this.complete(results);
}
};
Queue.prototype.clear = function () {
this.items = [];
this.results = [];
};
Queue.create = function () {
return new Queue;
};
return Queue;
})();
根据您给我们的信息,我的最佳猜测是,您正在将对
Queue.prototype.flush
函数对象的引用传递给某个异步函数,以便将其用作回调。如果这是真的,flush()
的调用方式如下:
myQueue.flush();
var myCallback = function() {
myQueue.flush();
};
ayncFunction(myCallback);
函数ayncFunction(回调){
//做点什么
回调();
}
ayncFunction(myQueue.flush);
。。。而不是像这样:
myQueue.flush();
var myCallback = function() {
myQueue.flush();
};
ayncFunction(myCallback);
由于函数是单独调用的,而不是在对象上调用,此
将设置为窗口
(除非您正在使用,在这种情况下,它是未定义的
)
您可以通过将对myQueue.flush()
的调用包装到函数中来避免此问题,如下所示:
myQueue.flush();
var myCallback = function() {
myQueue.flush();
};
ayncFunction(myCallback);
这是因为myCallback
变成了myQueue
周围的
解决此问题的另一种方法是使用将函数与其上下文(即应在其上调用函数的对象)联系起来。哪一行?你认为这是什么,结果是什么?通过删除不相关的位(而不仅仅是删除;您可能需要围绕删除进行重构!)将问题缩小到5-6行代码中@LightnessRacesinOrbit在flush方法中。我希望这是Queue的实例,而不是null。我问的是一个更一般的问题,而不是解决这个精确的问题:什么时候这不是原型的实例?如果你有一个一般的问题,那么你应该给出一个一般的测试用例。仔细看看
这个的含义——它不关心任何“原型”。它最初只是碰巧表示原型,因为它与当前函数的所有者相关。显然,您现在使用的是一个新函数。实际上,此
将引用“方法”的所有者,即窗口
。这是对正在发生的事情的正确解释。我将尝试第一种方法。bind()非常有效,谢谢@PPvG。我只需要创建一个新函数:var func=queue.flush.bind(queue);并将其作为回调传递。简单。