JavaScript setTimeout,使用call来改变它

时间:2013-11-26 15:20:08

标签: javascript jquery

我有两个简单的链接,点击时应等待一秒钟,然后添加一个更改文本颜色的类。工作版使用$.proxy和非工作版本我正在尝试使用本机JavaScript来更改this的含义。为什么btnWaitNoProxy仍然指的是全局对象?

fiddle

代码:

var obj = {
            wait: function () {
                setTimeout(function () {
                    console.log('inside the setTimeout');
                    $(this).addClass('lesson');
                    //refers to global object in the console
                }, 1000);
            }
        };

$('#btnProxy').on('click', function () {
            console.log('preparing to add class...');
            setTimeout($.proxy(function () {
                $(this).addClass('lesson')
                console.log(this);
            }, this), 1000);
        });
        $('#btnWaitNoProxy').on('click', function () {
            console.log(this);
            //call still refers to the global object
            obj.wait.call(this);
        });

2 个答案:

答案 0 :(得分:2)

因为您在setTimeout中使用wait,所以默认情况下,传递给setTimeout的回调方法将在全局上下文中执行。

一种可能的解决方案是使用$ .proxy(),因为你再次使用setTimeout处理程序

var obj = {
    wait: function () {
        setTimeout($.proxy(function () {
            console.log('inside the setTimeout');
            $(this).addClass('lesson');
            //refers to global object in the console
        }, this), 1000);
    }
};

另一种方法是使用像

这样的闭包变量
var obj = {
    wait: function () {
        var self = this;
        setTimeout(function () {
            console.log('inside the setTimeout');
            $(self).addClass('lesson');
            //refers to global object in the console
        }, 1000);
    }
};

答案 1 :(得分:0)

  

当您将方法传递给setTimeout()(或任何其他函数)时,将使用错误的this值调用该方法。

     

setTimeout()执行的代码在一个单独的执行上下文中运行,该函数从中调用它。因此,被调用函数的this关键字将被设置为窗口(或global)对象;它与调用this的函数的setTimeout值不同。

     

来源: MDN — window.setTimeout

有很多解决方案:

  1. 使用$.proxy
  2. 使用Function.prototype.bind
  3. 别名this