2

我有一个看起来像这样的应用程序对象构造函数:

var app = function(loadedsettings) {

    return {
        init: function() {          
            this.loop();
        },

        loop: function() {
            this.update();
            window.requestAnimationFrame(this.loop);
        },

        update: function() {
            //loop through settings and call update on every object.
        },

        settings: [
             //array of settings objects, all with update methods. 
        ]
    };
}

然后当我这样做时:

var theApp = app(settings);
theApp.init();

我得到:

Uncaught TypeError: Object [object global] has no method 'update'

因为在调用 requestAnimationFrame 时,循环函数内部的 this-value 被设置为 window。

有人知道如何调用 requestAnimatinFrame 并将“theApp”对象设置为 this 值吗?

4

2 回答 2

10

您可以创建一个绑定函数(带有一个固定的this),并将其传递给 requestAnimationFrame:

var app = function(loadedsettings) {

    return {
        init: function() {          
            this.loop();
        },

        loop: function() {
            this.update();
            window.requestAnimationFrame(this.loop.bind(this));
        },

        update: function() {
            //loop through settings and call update on every object.
        },

        settings: [
             //array of settings objects, all with update methods. 
        ]
    };
}

认为支持 requestAnimationFrame 的浏览器也将支持 Function.prototype.bind,但如果您遇到不支持的浏览器,则可以使用 polyfill。

于 2013-05-14T23:05:29.600 回答
1

您需要缓存对以下内容的引用this

var app = function(loadedsettings) {
    var self = this;
    return {
        init: function() {          
            self.loop();
        },

        loop: function() {
            self.update();
            window.requestAnimationFrame(self.loop);
        },
        ** snip **
        ...
于 2013-05-14T22:56:53.113 回答