Javascript 当该值为空时

Javascript 当该值为空时,javascript,Javascript,我试图为接受回调的函数实现一个简单的队列。我的问题是,在flush方法中,当正在执行的操作是一些长时间运行的事情(在我的例子中是indexedDB调用)时,“this”为null。我以前从未经历过这种行为,所以请告诉我发生了什么 代码如下: var Queue = (function () { function Queue() { }; Queue.prototype.items = []; Queue.prototype.results = []; Q

我试图为接受回调的函数实现一个简单的队列。我的问题是,在flush方法中,当正在执行的操作是一些长时间运行的事情(在我的例子中是indexedDB调用)时,“this”为null。我以前从未经历过这种行为,所以请告诉我发生了什么

代码如下:

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);并将其作为回调传递。简单。