Javascript 通过对象内的setTimeout自调用函数

Javascript 通过对象内的setTimeout自调用函数,javascript,function,object,self-invoking-function,Javascript,Function,Object,Self Invoking Function,我想通过setTimeout在同一个对象方法中调用js对象的方法: var ads = { init: function() { ads.display_ads(); }, display_ads: function() { console.log('Displaying Ads'); setTimeout('ads.display_ads()', 5000); } } 但是,我收到以下错误消息: ads is not defined setT

我想通过
setTimeout
在同一个对象方法中调用js对象的方法:

var ads = {

  init: function() {
    ads.display_ads();
  },

  display_ads: function() {
     console.log('Displaying Ads');
     setTimeout('ads.display_ads()', 5000);
  }
}
但是,我收到以下错误消息:

ads is not defined

setTimeout('ads.display_ads()', 2000);
我错过了什么?如何在setTimeout函数中更改字符串

谢谢你的帮助


编辑:我在mac上使用firefox。

只需将其更改为
ads.display\u ads
,注意这不是
字符串。i、 e

var ads = {
    init: function() {
        ads.display_ads();
    },
    display_ads: function() {
        console.log('Displaying Ads');
        setTimeout(ads.display_ads, 5000);
    }
}
正如@FelixKling在下面的评论中指出的那样,要注意
这个
ads.display\u ads
中所指的内容。如果通过
ads.init()
ads.display\u ads()
调用
ads.display\u ads
,则该
将成为
ads
对象。但是,如果通过
setTimeout
调用此
将是
窗口

但是,如果上下文很重要,可以将匿名函数传递给
setTimeout
,该函数反过来调用
ads.display\u ads()


试试这个。显示广告

我建议您在引用
ads

因此,代码如下所示:

var ads = {

  init: function() {
    this.display_ads();
  },

  display_ads: function() {
     console.log('Displaying Ads');
     setTimeout(this.display_ads, 5000);
  }
}

所以,正如杰克·克拉克森所说,ads.display\u广告:

setTimeout(hitch(ads, ads.display_ads), 5000);
不同之处在于,您应该使用“挂接”功能:

function hitch(scope, callback) {
    return function () {
         return callback.apply(scope, Array.prototype.slice.call(arguments));
    }
}
此函数将确保回调的范围是ads对象。有关应用功能的说明,请参见MDN:

function hitch(scope, callback) {
    return function () {
         return callback.apply(scope, Array.prototype.slice.call(arguments));
    }
}

的工作对我帮助很大。我试图让一个游戏循环工作,但似乎
这个
引用的是
窗口
,而不是我创建的对象。下面是目前正在运行的代码的最低版本(它只需计算每秒数并将其写入div“content”):


而不是
setTimeout(this.run,1000)
我使用
self
而不是
this
来阐明对象的含义(如所建议的)。我想我应该添加这个,因为我使用的是一个对象构造函数,并且有一个稍微不同的语法。尤其是使用
ads.method
不起作用(因为我猜游戏还不是一个对象),所以我不得不使用上一个解决方案。

如果您将字符串传递给
setTimeout
,它将在全局范围内进行评估。显然,
ads
未在全局范围内定义。解决方法是不传递字符串。这与您在与对象属性关联的函数中调用
setTimeout
无关。我在chrome上没有看到任何错误。你在哪个浏览器上?在setTimout中使用字符串和在
init
中使用eval()一样糟糕,你真的应该调用
this.display_ads()
而不是
ads…
。否则,如果重命名变量或将对象分配给另一个变量等,则可能会遇到问题。在
display\u ads
中,
将参考
窗口
。这可能不是一个问题,但必须指出。感谢您提供的详细答案。这让人大开眼界很高兴它有帮助:-)感谢@FelixKling也标记了绑定问题。这只会第一次起作用。当第二次执行
this.display\u ads
时(通过
setTimeout
),
此.display\u ads
未定义,因为
指的是
窗口
function hitch(scope, callback) {
    return function () {
         return callback.apply(scope, Array.prototype.slice.call(arguments));
    }
}
function Game(model, renderer){
    this.model = model;
    this.renderer = renderer;
    this.run = function(){
        this.model.update();
        this.renderer.draw(this.model);
        var self = this;
        setTimeout(function(){self.run();}, 1000);
    };
}
function Model(){
    this.data = 0;
    this.update = function(){
        this.data++;
    };
}
function Renderer(){
    this.draw = function(model, interpolation){
        document.getElementById("content").innerHTML = model.data;
    };
}
var game = new Game(new Model(), new Renderer());
game.run();