【问题标题】:Objects, their instances and setTimeOut effect对象、它们的实例和 setTimeOut 效果
【发布时间】:2011-05-14 08:01:09
【问题描述】:

所以我正在尝试学习 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
    }
}

};

我的脚本在 FireFox 4 中的 GreaseMonkey 上运行。在我的代码中,我使用上面的函数/类来创建一个对象,如下所示。

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容器内的结果页面内容返回给回调函数。

首先,一般问题:在我调用clearTimeOut 函数后,nAntiFreeze 的值不会重置为 null 或任何值。这是正常的吗?

第二个问题:为什么当超时用完时,我得到错误that.loadPage() is not a function? GM_log(that) 告诉我 [object Object]。

这个问题的人可以通过使用var that = this 使其工作。但为什么它对我不起作用? Custom Object calling Methods with setTimeout loses scope

编辑: 第三个问题:如果我创建一百万个对象会发生什么。浏览器完成工作后会摆脱它们吗?因为我肯定无法释放它们,因为这个对象使用异步 ajax 调用,这意味着我不能这样做

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

oStocker = null 将在我的对象完成工作之前被调用。

谢谢

【问题讨论】:

    标签: javascript object greasemonkey settimeout


    【解决方案1】:

    首先,nAntiFreezesetTimeout 返回的原始值。您将该值传递回clearTimtout,以便它知道要清除哪个超时。调用clearTimeout 不会影响nAntiFreeze 的值。

    其次,that.loadPage 是未定义的,因为在调用 doStock() 时,that 引用了 this(其中它被称为带有 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 的构造函数没有多大意义,您可以使用 Richard Cornford 的模块模式并使用闭包进行继承。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-09
      • 1970-01-01
      • 2019-11-21
      • 1970-01-01
      • 2014-07-18
      相关资源
      最近更新 更多