Объекты, их экземпляры и эффект setTimeOut - PullRequest
2 голосов
/ 14 мая 2011

Итак, я пытаюсь научиться объектно-ориентированному программированию на javascript.

function doStock() {    //my class
var that = this;
var nAntiFreeze = null;   // timeout ID
var getContent = function(oInPageContainer) {  
    GM_log('Antifreeze, before clear ' +nAntiFreeze);
    //clearTimeout(nAntiFreeze);
    GM_log('Antifreeze, after clear ' +nAntiFreeze);
};

return {
    sLink : "",
    oList : "",
    sSplitOperator : ";",
    reset : function() {
        this.sLink = '';
        this.oList = '';
        this.sSplitOperator = ';';
        nAntiFreeze = null;
    },
    loadPage : function() {
        if (this.sLink.length == 0) return;
        if (this.oList.length == 0) return;
        nAntiFreeze = setTimeout(function(){GM_log(that); that.loadPage();},30000);
        GM_log('antifreeze ' + nAntiFreeze);
        getPageAsync2(this.sLink,false,getContent);  //GM_xmlhttprequest
    }
}

};

Мой скрипт выполняется на GreaseMonkey в FireFox 4. В моем коде я использую вышеуказанную функцию / класс для создания объекта следующим образом.

var oStocker = new doStock();
oStocker.sLink = 'www.somepage.com';
oStocker.oList = 'some list, may be a string line or the array object';
oStocker.loadPage();

getPageAsync2 функция вызывает GM_xmlhttprequest, а затем возвращает содержимое страницы результатов в контейнере div в функцию обратного вызова.

Во-первых, общий вопрос: значение nAntiFreeze не сбрасывается в ноль или что-либо еще после того, как я вызову функцию clearTimeOut. Это нормально?

Второй вопрос: почему по истечении времени ожидания я получаю ошибку that.loadPage() is not a function? GM_log (тот) говорит мне [объект объекта].

Человек по этому вопросу смог заставить его работать, используя var that = this. Но почему это не работает для меня? Пользовательские методы вызова методов с setTimeout теряют область видимости

РЕДАКТИРОВАТЬ: Третий вопрос: что произойдет, если я создам миллион объектов. Будет ли браузер избавляться от них, когда они закончат работать? Потому что я уверен, что не могу освободить их, так как этот объект использует асинхронные вызовы ajax, а это значит, что я не могу сделать

var oStocker = new doStock();
oStocker.loadPage();
oStocker = null;

oStocker = null будет вызван еще до того, как мой объект завершит работу.

Спасибо

1 Ответ

1 голос
/ 14 мая 2011

Во-первых, nAntiFreeze - это примитивное значение, возвращаемое setTimeout.Вы передаете это значение обратно clearTimtout, чтобы он знал, какое время ожидания сбрасывается.Вызов clearTimeout не влияет на значение nAntiFreeze.

Во-вторых, that.loadPage не определено, поскольку that ссылается на this, когда вызывается doStock() (где он вызывается как конструкторс new он ссылается на новый объект).Но ваша функция не возвращает этот объект (т.е. конструктор this), она возвращает объект после return, для которого функция loadPage() является методом.Другими словами, вы ссылаетесь не на тот объект.

Когда вы вызываете oStocker.loadPage(), его ключевое слово this ссылается на объект oStocker, но функция, переданная в setTimeout, ссылается на that, который имеет замыкание в конструкторе this.

Должно работать следующее:

loadPage : function() {

    // Declare that here
    var that = this;

    if (this.sLink.length == 0) return;
    if (this.oList.length == 0) return;

    // If called as oStocker.loadPage(), this (and that) is
    // the oStocker object.
    nAntiFreeze = setTimeout(function(){GM_log(that); that.loadPage();},30000);
    GM_log('antifreeze ' + nAntiFreeze);
    getPageAsync2(this.sLink,false,getContent);  //GM_xmlhttprequest
}

Нет особого смысла использовать конструктор, который не возвращает его this, вы можете использовать шаблон модуля Ричарда Корнфорда и использовать замыкания для наследования.

...