【问题标题】:Referencing "this" inside setInterval/setTimeout within object prototype methods [duplicate]在对象原型方法中的 setInterval/setTimeout 中引用“this”[重复]
【发布时间】:2011-12-14 23:55:01
【问题描述】:

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

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

【问题讨论】:

标签: javascript scope lexical-scope


【解决方案1】:

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

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

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

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

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

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

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

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

胖箭头匿名函数从周围的函数中保留this,因此无需使用var that = this 技巧。要查看您是否可以使用此功能,请参阅this one 之类的兼容性表。

使用绑定函数

最后一个替代方法是使用 Function.prototype.bind 之类的函数或您喜欢的 Javascript 库中的等效函数。

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

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

【讨论】:

【解决方案2】:

我做了一个代理类:)

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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-31
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    • 2021-10-02
    • 1970-01-01
    • 2017-03-31
    相关资源
    最近更新 更多