Самостоятельно вызывая функцию через setTimeout внутри объекта - PullRequest
0 голосов
/ 29 февраля 2012

Я бы хотел вызвать метод объекта js в том же методе объекта через setTimeout:

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?

Спасибо за вашу помощь!

Редактировать: я использую Firefox на Mac.

Ответы [ 4 ]

2 голосов
/ 29 февраля 2012

Просто измените его на ads.display_ads, обратите внимание, что это не String. т.е.

var ads = {
    init: function() {
        ads.display_ads();
    },
    display_ads: function() {
        console.log('Displaying Ads');
        setTimeout(ads.display_ads, 5000);
    }
}

Как @FelixKling указывает в своем комментарии ниже, будьте осторожны с тем, на что ссылается this в ads.display_ads. Если ads.display_ads вызывается через ads.init() или ads.display_ads() this будет ads Object. Однако при вызове через setTimeout this будет window.

Если контекст важен, вы можете передать анонимную функцию в setTimeout, которая в свою очередь вызывает ads.display_ads():

setTimeout(function() {
    ads.display_ads();
}, 5000);

или

var self = this;
setTimeout(function() {
    self.display_ads();
}, 5000);
0 голосов
/ 04 февраля 2014

Ответ из jabclab очень помог мне.Я пытался заставить игровой цикл работать, но, похоже, this ссылался на window вместо созданного мной объекта.Вот минимальная версия запущенного в настоящее время кода (он просто подсчитывает каждую секунду и записывает его в div "content"):

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

Вместо setTimeout(this.run, 1000) я использовал self вместо this, чтобы уточнить, какой объект имеется в виду (как предложено jabclab ).Думаю, я бы добавил это, потому что я использую конструктор объекта и немного другой синтаксис.Особенно использование ads.method не сработало (потому что Game - еще не объект, я думаю), поэтому мне пришлось использовать последнее решение.

0 голосов
/ 29 февраля 2012

Итак, как сказал Джейк Кларксон, ads.display_ads:

setTimeout(hitch(ads, ads.display_ads), 5000);

Разница в том, что вы должны использовать функцию "заминка":

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

Эта функция гарантирует, что областью обратного вызова является ваш рекламный объект. См. MDN для описания функции применения:

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply

0 голосов
/ 29 февраля 2012

попробуй this.display_ads,

Я бы рекомендовал вам использовать это для ссылок ads

поэтому код будет выглядеть так:

var ads = {

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

  display_ads: function() {
     console.log('Displaying Ads');
     setTimeout(this.display_ads, 5000);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...