参数需要一个函数,但不接受函数

时间:2014-05-27 04:13:16

标签: javascript html5-canvas

完整代码:http://paste2.org/Fn3Y89am

//render class
(function(){
    function Render(){
        this.canvas = document.getElementById('game');
        this.ctx = this.canvas.getContext('2d');

        this.ctx.fillStyle = 'black';
        this.ctx.font = '16pt Helvetica';

        this.lastFrameTime = Date.now();
    }

    Render.prototype.drawFrame = function(){
        var self = this;

        var now = Date.now();
        var dt = now - self.lastFrameTime;

        //request next animation frame, make this
        //function the callback
        requestAnimationFrame(self.drawFrame);
    }

    Game.Render = Render;
})();
requestAnimationFrame中的

Render.prototype.drawFrame需要将一个函数传递给它。正如您在我的代码中看到的那样,我试图将作为render类的一部分的drawFrame函数传递给参数。出于某种原因,它一直说这不是一个功能。

Uncaught TypeError: Failed to execute 'requestAnimationFrame' on 'Window': The callback provided as parameter 1 is not a function. 

这是为什么?我看了几个其他的例子,我做的和他们一样。不能完全理解我做错了什么。谢谢你的帮助!

2 个答案:

答案 0 :(得分:3)

问题可能在于您或其他人如何调用drawFrame。如果不将drawFrame作为Render对象的属性调用,那么this的值在drawFrame中将是错误的。如果this的值错误,则self的值将出错,self.drawFrame将不是函数。

事实证明,即使最初正确调用self.drawFrame()requestAnimationFrame()调用它时也不再正确,因为当您将self.drawFrame作为参数传递时,所有传递的是函数引用,然后当requestAnimationFrame将其作为回调调用时,对self的引用将丢失,因此this内的drawFrame将会出错。

我不知道你是如何第一次调用drawFrame,但如果这是正确的,那么你可以像这样修复你的问题:

Render.prototype.drawFrame = function(){
    var self = this;

    var now = Date.now();
    var dt = now - self.lastFrameTime;

    //request next animation frame, make this
    //function the callback
    requestAnimationFrame(self.drawFrame.bind(self));
}

或者,与旧浏览器兼容的方法:

Render.prototype.drawFrame = function(){
    var self = this;

    var now = Date.now();
    var dt = now - self.lastFrameTime;

    //request next animation frame, make this
    //function the callback
    requestAnimationFrame(function() {self.drawFrame();});
}

如果没有正确拨打obj.drawFrame()的电话(你没有透露的话),那么你也必须解决这个问题。


这里要记住两件事很重要。

  1. this指针由函数的调用方式决定。要使drawFrame()工作,必须将其称为obj.drawFrame(),其中objRender个对象。

  2. 当您将参数传递为self.drawFrame时,对self的引用会丢失,drawFrame()无法正确调用requestAnimationFrame()。这就是为什么你需要一个中间函数(.bind()创建,但也可以用你自己的匿名函数完成),以便正确地调用drawFrame()

答案 1 :(得分:1)

在你的背景下,自我实际功能不是吗?

Render.prototype.drawFrame = function()然后你不情愿地致电self=this,在这种情况下this是您当前所处的实际功能。您可以尝试使用console.log(self)并查看你得到了什么