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()一次,它应该可以工作。这是未经测试的代码,这个,我今天有点发烧,但它应该。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 回答