使用setTimeout()时如何使用call()设置`this`的值?

and*_*ies 1 javascript prototype this settimeout

我在javascript中制作一个简单的游戏.这些是我的玩家方法(有问题的部分是在玩家击中水后半秒钟调用重置方法):

Player.prototype = {
    update : function(){
        // player control and edge of screen detection
        // TODO factor out hardcoding into sprite width constants
        if (this.keyPressed === 'right' && this.x < 400){
            this.x += 100;
        }
        if (this.keyPressed === 'left' && this.x > 10){
            this.x += -100;
        }
        if (this.keyPressed === 'up' && this.y > 10){
            this.y -= 83;
        }
        if (this.keyPressed === 'down' && this.y < 400){
            this.y -= -83;
        }
        // reset key press
        this.keyPressed = null;

        // if reaches water, reset position
        if (this.y < 60) {
            setTimeout(this.reset, 500);
        }
    },
    reset : function(){
        // TODO factor these constants out
        // console.logs for testing
        console.log("a");
        console.log(this);
        this.x = 200;
        this.y = 405;
        console.log(this.x);
    },
    render : function(){
        ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
    },
    handleInput : function(e){
        this.keyPressed = e;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,在update调用时reset,关键字this不受约束player,而是绑定到window.

我可以只是包含player.x和player.y进入reset,但这是否会破坏在原型中编写方法的意义?

我有想法使用call()设置值this,但我似乎无法使用它setTimeout().这不起作用(错误:对象不是函数):

setTimeout(this.reset.call, 500, this);
Run Code Online (Sandbox Code Playgroud)

..这两个都没有(重置正确但立即执行):

setTimeout(this.reset.call(this), 500);
Run Code Online (Sandbox Code Playgroud)

所以,我怎么设置this来player并将它传递给reset带setTimeout?

jcu*_*bic 6

你可以使用bind:

setTimeout(this.reset.bind(this), 500);
Run Code Online (Sandbox Code Playgroud)


Que*_*tin 5

你没有.call将立即调用该函数,以便您将其返回值传递给setTimeout.

请bind改用.bind生成一个新函数,该函数使用不同的上下文(和默认变量)调用原始函数.

setTimeout(this.reset.bind(this), 500);
Run Code Online (Sandbox Code Playgroud)