JavaScript:在我的函数中避免全局变量

时间:2012-09-20 18:14:33

标签: 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类中拥有私有方法的方式。 有人可以告诉我如何实现这个目标吗?

由于

2 个答案:

答案 0 :(得分: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()一次即可。这是未经测试的代码,这个,今天我有点发烧,但应该。 IMO,代码更少,效率更高。

答案 1 :(得分:0)

您可以将其封闭在封闭中:

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

如果您在此关闭之外不需要redirectTimer,则可以移除window.redirectTimer =部分。