2016-07-28 8 views
1

updateSession()にアクセスすると、$sessionTimeLeftは未定義です。しかし、initiate()の中で$sessionTimeLeftの宣言と代入を移動したとき、正しいjQueryオブジェクトが得られました。閉鎖のためinitiate()の中に宣言された場合は$sessionTimeLeftにアクセスできると思います。しかし、$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秒毎です。