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

JavaScript:在我的函数中避免全局变量,javascript,Javascript,我试图了解可以用来避免在JavaScript中使用全局变量的各种技术 考虑以下代码,该代码在倒计时后重定向到URL: var _redirectTimer; function startRedirectTimer() { clearTimeout(_redirectTimer); var redirectTimer = function(timeLeft) { if(timeLeft == 0) { // redirect to application

我试图了解可以用来避免在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()
。然而,
\u redirectTimer
是一个全局变量,我不想公开它。 理想情况下,我希望这个变量是
startRedirectTimer()
中的一个“state”变量,类似于单例java类中的私有方法。 有人能建议我如何做到这一点吗


谢谢

您可以将其封闭起来:

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

如果您不需要此闭包之外的
redirectTimer
,您可以删除
window.redirectTimer=
部分。

那么,快速绕过变量的方法就是在有问题的部分周围包装一个额外的函数:

(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
和往常一样,您可以通过向全局对象公开超时函数来选择何时调用超时函数。但是,如果我理解正确,您正在寻找一种包含
\u 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()
,它就会工作。这是未经测试的代码,我今天有点发烧,但它应该。依我看,代码更少,效率更高。

那么我如何调用StartDirectTimer()?我只需要调用这个方法,但它又需要调用redirectTimer()等等,看起来我看错了你的一些代码。这似乎有点多余,为什么你不能设置一个60秒的计时器,然后再重定向?@Kolink,我也注意到了,但我认为OP想在那里实现某种倒计时系统,有一件事……我不希望每次都调用clearTimeout()。仅当首次调用StartDirectTimer时,而不是在递归调用时。您的第一个解决方案似乎工作得最好
\u重定向计时器在第一次调用时未定义,因此清除它实际上没有任何作用。当您意外地调用函数两次时,在每次调用时清除它应该可以防止超时停留在1秒的间隔。我不知道我是否明白你想做什么