2012-07-04 102 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)