0

JavaScriptでグローバル変数の使用を回避するために使用できるさまざまな手法に頭を悩ませようとしています。

カウントダウンタイマーの後にURLへのリダイレクトを実行する次のコードについて考えてみます。

var _redirectTimer;
function startRedirectTimer() {
    clearTimeout(_redirectTimer);

    var redirectTimer = function(timeLeft) {
    if(timeLeft == 0) {
        // redirect to application path
        var redirectURL = window.location.protocol+"//"+window.location.host + "/" + location.pathname.split("/")[1];
        window.location.replace(redirectURL);
        return;
    } else {
        timeLeft--;
        _redirectTimer = setTimeout(function () {redirectTimer(timeLeft)}, 1000);
    }   
}   
redirectTimer(60);  

}

私のクライアントコードはこれまでにのみ呼び出しますstartRedirectTimer()。ただし、_redirectTimerこれは公開したくないグローバル変数です。startRedirectTimer()理想的には、この変数を、シングルトンJavaクラスのプライベートメソッドと同じように、内の「状態」変数にしたいと思います。誰かが私がこれを達成する方法についてアドバイスできますか?

ありがとう

4

2 に答える 2

1

さて、変数を回避する簡単な方法は、問題のセクションの周りに追加の関数をラップすることです。

(function()
{//wrapper function
    var _redirectTimer;
    function startRedirectTimer()
    {
        clearTimeout(_redirectTimer);
        var redirectTimer = function(timeLeft) {
        if(timeLeft == 0)
        {
            // redirect to application path
            var redirectURL = window.location.protocol+"//"+window.location.host + "/" + location.pathname.split("/")[1];
            window.location.replace(redirectURL);
            return;
        }
        else
        {
            timeLeft--;
            _redirectTimer = setTimeout(function () {redirectTimer(timeLeft)}, 1000);
        }   
    }   
    redirectTimer(60);  
})();//call wrapper function

いつものように、タイムアウト関数をグローバルオブジェクトに公開することで、いつ呼び出すかを選択できます。_redirectTimerただし、私が正しく理解していれば、関数を含むか、関数にリンクする方法を探していますstartRedirectTimer(明らかに、呼び出しのたびに状態が失われることはありません)。これは、いくつかの方法で可能です。

function startRedirectTimer()
{
    //as you would, only: add this line
    var _redirectTimer = startRedirectTimer._redirectTimer;
}
startRedirectTimer._redirectTimer;//functions are objects, so assign properties and methods at will

これらのプロパティとメソッドは関数が存続する限り存続するため、呼び出しのたびに値がリセットされることはありません。欠点:公的にアクセス可能であり、誤って再定義される可能性があります。
クロージャーは、次のような場合に最適です。

var startRedirectTimer = (function()
{
    var _redirectTimer,timeLeft = 60;//initial value here
    var redirectURL = window.location.protocol+"//"+window.location.host + "/" + location.pathname.split("/")[1];//
    return function ()
    {
        clearTimeout(_redirectTimer);
        if (timeLeft === 0)
        {
            return window.location.replace(redirectURL);
        }
        timeLeft--;
        _redirectTimer = setTimeout(startRedirectTimer,1000);//just call the main function again
    }
})();//return value of this function will be the actual startRedirectTimer function

上記のコードで物事を動かすには、startRedirectTimer()1回呼び出すだけで、機能するはずです。これはテストされていないコードで、今日は少し熱っぽいですが、そうすべきです。IMO、より少ないコード、そしてより効率的。

于 2012-09-20T18:35:22.813 に答える
0

あなたはそれをクロージャーで囲むことができます:

(function() {
    var _redirectTimer, redirectTimer;
    window.redirectTimer = redirectTimer = function() {
        // ......
    }
    redirectTimer(60);
})();

redirectTimerこのクロージャーの外側が必要ない場合は、window.redirectTimer =パーツを取り外すことができます。

于 2012-09-20T18:18:26.630 に答える