Javascript 在对象原型方法中的 setInterval/setTimeout 中引用“this”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7890685/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 03:58:03  来源:igfitidea点击:

Referencing "this" inside setInterval/setTimeout within object prototype methods

javascriptscopelexical-scope

提问by Huck

Normally I'd assign an alternative "self" reference when referring to "this" within setInterval. Is it possible to accomplish something similar within the context of a prototype method? The following code errors.

通常,当在 setInterval 中引用“this”时,我会分配一个替代的“self”引用。是否有可能在原型方法的上下文中完成类似的事情?以下代码错误。

function Foo() {}
Foo.prototype = {
    bar: function () {
        this.baz();
    },
    baz: function () {
        this.draw();
        requestAnimFrame(this.baz);
    }
};

回答by hugomg

Unlike in a language like Python, a Javascript method forgets it is a method after you extract it and pass it somewhere else. You can either

与 Python 之类的语言不同,Javascript 方法在您提取它并将其传递到其他地方后会忘记它是一个方法。你可以

Wrap the method call inside an anonymous function

将方法调用包装在匿名函数中

This way, accessing the bazproperty and calling it happen at the same time, which is necessary for the thisto be set correctly inside the method call.

这样,访问baz属性和调用它是同时发生的,这对于this在方法调用中正确设置是必要的。

You will need to save the thisfrom the outer function in a helper variable, since the inner function will refer to a different thisobject.

您需要将this来自外部函数的保存在辅助变量中,因为内部函数将引用不同的this对象。

var that = this;
setInterval(function(){
    return that.baz();
}, 1000);

Wrap the method call inside a fat arrow function

将方法调用包装在一个粗箭头函数中

In Javascript implementations that implement the arrow functionsfeature, it is possible to write the above solution in a more concise manner by using the fat arrow syntax:

在实现箭头函数功能的Javascript 实现中,可以使用粗箭头语法以更简洁的方式编写上述解决方案:

setInterval( () => this.baz(), 1000 );

Fat arrow anonymous functions preserve the thisfrom the surrounding function so there is no need to use the var that = thistrick. To see if you can use this feature, consult a compatibility table like this one.

胖箭头匿名函数保留了this来自周围函数的信息,因此无需使用该var that = this技巧。要查看您是否可以使用此功能,请查阅像这样的兼容性表。

Use a binding function

使用绑定函数

A final alternative is to use a function such as Function.prototype.bind or an equivalent from your favorite Javascript library.

最后一种选择是使用函数,例如 Function.prototype.bind 或您最喜欢的 Javascript 库中的等效函数。

setInterval( this.baz.bind(this), 1000 );

//dojo toolkit example:
setInterval( dojo.hitch(this, 'baz'), 100);

回答by gloryonjesus

i made a proxy class :)

我做了一个代理类:)

function callback_proxy(obj, obj_method_name)
{
    instance_id = callback_proxy.instance_id++;
    callback_proxy.instances[instance_id] = obj;
    return eval('fn = function() { callback_proxy.instances['+instance_id+'].'+obj_method_name+'(); }');
}
callback_proxy.instance_id = 0;
callback_proxy.instances = new Array();

function Timer(left_time)
{
    this.left_time = left_time; //second
    this.timer_id;

    this.update = function()
    {
        this.left_time -= 1;

        if( this.left_time<=0 )
        {
            alert('fin!');
            clearInterval(this.timer_id);
            return;
        }
    }

    this.timer_id = setInterval(callback_proxy(this, 'update'), 1000);
}

new Timer(10);