2012-09-20 107 views
0

我想讓我的腦袋圍繞可以用來避免在JavaScript中使用全局變量的各種技術。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類中擁有私有方法的方式。 有人可以告訴我如何實現這一目標嗎?

感謝

回答

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()一次,它應該工作。這是未經測試的代碼,今天,我有點發燒,但它應該。國際海事組織,更少的代碼,更高效。

+0

幾乎在那裏,有一件事......我不希望每次都調用clearTimeout()。只有在第一次調用startRedirectTimer時,而不是在遞歸調用時。你的第一個解決方案似乎效果最好 – DJ180

+0

在第一次調用時未定義'_redirectTimer',因此清除它並不會真的做任何事情。每隔一次呼叫清除一次呼叫應該防止當你不小心調用該功能兩次時,時間限制會持續1秒。不知道我是否完全明白你在做什麼 –

0

您可以將其括在一個封閉:

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

如果您不需要redirectTimer這個封閉外,你可以刪除window.redirectTimer =部分。

+0

那麼我該如何調用startRedirectTimer()呢?我只需要調用這個方法,但是它又需要調用redirectTimer() – DJ180

+0

等一下,它看起來像我讀了一些你的代碼。它似乎有點多餘,爲什麼你不能只設置一個計時器60秒,然後重定向? –

+0

@Kolink,我注意到了,但是我認爲OP要實現某種倒計時系統 –