2012-07-04 76 views
3

我有一个类,我试图用来管理客户端的会话,它看起来像这样:的Javascript setInterval的范围界定问题

var sessionmanager; 

sessionmanager = (function() { 

    sessionmanager.name = 'sessionmanager'; 

    function sessionmanager(timeout, action) { 
    if (action != null) { 
     this.action = action; 
    } else { 
     this.action = null; 
    } 
    if (timeout != null) { 
     this.timeout = timeout * 60; 
    } else { 
     this.timeout = 0; 
    } 
    } 

    sessionmanager.prototype.run = function() { 
    return window.setInterval(this.tick, 1000); 
    }; 

    sessionmanager.prototype.sessionExpired = function() { 
    if (this.action != null) { 
     window.navigate("timeout.asp"); 
    } 
    }; 

    sessionmanager.prototype.setTimeout = function(timeout) { 
    return this.timeout = timeout; 
    }; 

    sessionmanager.prototype.tick = function() { 
    this.timeout -= 1; 
    if (this.timeout < 1) { 
     return sessionExpired(); 
    } 
    }; 

    return sessionmanager; 

})(); 

然而,当我调试tick函数内部是从内部被称为setInterval回调我得到this.timeout = NaN

我猜我的作用域不正确?请帮助?我是JavaScript新手...

回答

6

如果setInterval调用该函数,则它不会像您期望的那样设置this值。调用this.tick()确实设置正确,但只是传递函数,并以另一种方式调用它不。你必须在this值绑定到你想要的东西:

setInterval(this.tick.bind(this), 1000); 

这是可在新的浏览器,但也有垫片。

此外,您可能意思是this.sessionExpired(),因为这是它的定义。 return没有多大意义,因为setInterval不关心返回值。

+0

你也可以使用“那个”技巧: 'var that = this;返回setInterval(函数(){返回that.tick()},1000)' – hugomg

+0

我最终使用'那个'解决方案,因为我需要支持更旧的浏览器(诅咒你的asp!),但我很感激帮助! – FlyingStreudel

+0

@missingno:对。这里只是修复'this'值,所以我认为'.bind'是一个很好的解决方案。 – pimvdb

0

你有没有设置超时?你可能想要

sessionmanager.timeout=0; 

somwhere在类定义中。

+0

我在构造函数中this.timeout = 0? – FlyingStreudel

+0

一个实例具有'.timeout'值,而不是构造函数本身。 – pimvdb

+0

等等,这个''是指构造函数,而不是对象? – FlyingStreudel

0

在ES7的Javascript,你可以做到以下几点:

window.setInterval(::this.tick, 1000); 

双冒号语法::是一个捷径.bind(this)