用JavaScript创建队列并访问匿名函数中的全局变量

Creating a queue in JavaScript and access global variables in an anonymous function

本文关键字:函数 全局变量 访问 JavaScript 创建 队列      更新时间:2023-09-26

我并不精通JavaScript。我在下面有一个对象(Foo.bar),我想每100毫秒从队列中馈送和打印一个项目。

var Foo = Foo || {};
Foo.bar = {
    initialize: function () {
        this.feedQueue();
        this.consumeQueue();
    },
    queue: [],
    consumeQueue: function () {
        if (this.queue > 0) {
            var item = this.queue.shift();
            console.log(item);
        }
        setTimeout(function () {
            this.consumeQueue();
        }, 100);
    },
    feedQueue: function () {
        this.queue.push(Math.random());
        setTimeout(function () {
            this.feedQueue();
        }, 100);
    }
};
Foo.bar.initialize();

在consumerQueue函数中,"this.queue"从不更新。它总是空的。

有人能帮我解决我做错了什么吗?

您需要将作用域绑定到超时函数,否则this有不同的上下文。

setTimeout((function () {
    this.consumeQueue();
}).bind(this), 100);

Fiddle

为什么绑定,为什么参数?

setTimeout((function () {
    Foo.bar.consumeQueue();
}), 100);

在回调函数中,this等于window,因为在调用回调时省略了this

正如RienVaPlus在他的回答中所说,你可以使用像这样的绑定

setTimeout((function () {
    this.consumeQueue();
}).bind(this), 100);

或者您可以将this作为参数传递给调用函数

setTimeout(function (context) {
    context.consumeQueue();
}, 100, this);

在这两种情况下,如果你使用IE作为浏览器,你至少需要IE9

作为绑定或将其传递给回调函数的最后一种选择,这应该在IE9:之前工作

...
consumeQueue: function () {
    if (this.queue > 0) {
        var item = this.queue.shift();
        console.log(item);
    }
    var that = this;
    setTimeout(function () {
        that.consumeQueue();
    }, 100);
},
...