2016-07-28 131 views
1

當在下面的代碼中聲明時,$sessionTimeLeftupdateSession()內部訪問時未定義。但是當我在initiate()裏面移動$sessionTimeLeft聲明和賦值時,我得到了正確的jQuery對象。我想我可以訪問$sessionTimeLeft當它在initiate()內由於關閉而被聲明。但爲什麼$sessionTimeLeft超出我的原始代碼範圍?模塊內部的Javascript範圍問題

var session = (function SessionManager() { 
    var timeLeftInMs; 
    var timeLeftInMin; 
    var delay; // in ms 
    var $sessionTimeLeft = $('#dcSessionTimeLeft'); 

    /* Set up the module by setting the timeout and delay time. */ 
    function initiate(_timeout, _delay) { 
    timeLeftInMin = _timeout; 
    timeLeftInMs = timeLeftInMin * 60 * 1000;  
    delay = _delay; // delay in ms  

    setInterval(updateSession, delay); 
    } 

    function updateSession() { 
    timeLeftInMs -= delay; 
    timeLeftInMin = timeLeftInMs/60000; // convert ms to min.    

    $sessionTimeLeft.text(timeLeftInMin); 
    } 

    var publicAPI = { 
    initiate: initiate 
    }; 

    return publicAPI; 
})(); 

session.initiate(30,1000); 
+0

'session.initiate(30,1000)' –

+1

是'#dcSessionTimeLeft'當你把它分配給$''sessionTimeLeft裝? –

+1

請提供代碼來重現問題。 –

回答

1

這裏的問題是,當您嘗試訪問它時,#dcSessionTimeLeft可能尚未加載。因此,要確保在裝入一個方法是來包裝你的代碼在一個document.ready

$(function() { 
    var session = (function SessionManager() { 
    var timeLeftInMs; 
    var timeLeftInMin; 
    var delay; // in ms 
    var $sessionTimeLeft = $('#dcSessionTimeLeft'); 

    /* Set up the module by setting the timeout and delay time. */ 
    function initiate(_timeout, _delay) { 
    timeLeftInMin = _timeout; 
    timeLeftInMs = timeLeftInMin * 60 * 1000;  
    delay = _delay; // delay in ms  

    setInterval(updateSession, delay); 
    } 

    function updateSession() { 
    timeLeftInMs -= delay; 
    timeLeftInMin = timeLeftInMs/60000; // convert ms to min.    

    $sessionTimeLeft.text(timeLeftInMin); 
    } 

    var publicAPI = { 
    initiate: initiate 
    }; 

    return publicAPI; 
    })(); 

    session.initiate(30,1000); 
}); 
0

封閉在這種情況下也應該工作得很好。此代碼不起作用的原因是因爲您尚未正確調用會話功能。記住這個函數返回一個函數對象發起

最後的代碼行應該是

session.initiate(30,1000); 

這應該工作。重現我使用節點的問題。我將$ sessionTimeLeft變量更改爲字符串hello,並測試它是否仍然可以在updateSession函數中訪問。我的代碼是

var session = (function SessionManager() { 
    var timeLeftInMs; 
    var timeLeftInMin; 
    var delay; // in ms 
    var $sessionTimeLeft = "Hello"; 

    /* Set up the module by setting the timeout and delay time. */ 
    function initiate(_timeout, _delay) { 
    timeLeftInMin = _timeout; 
    timeLeftInMs = timeLeftInMin * 60 * 1000; 
    delay = _delay; // delay in ms 

    setInterval(updateSession, delay); 
    } 

    function updateSession() { 
    timeLeftInMs -= delay; 
    timeLeftInMin = timeLeftInMs/60000; // convert ms to min. 

    console.log($sessionTimeLeft); 
    } 

    var publicAPI = { 
    initiate: initiate 
    }; 

    return publicAPI; 
})(); 

session.initiate(30,1000); 

而且我得到的結果是

Hello 
Hello 
Hello 
Hello 
Hello 

每1秒。