setInterval始终将deltaSec的初始值显示为“未定义”

时间:2018-12-24 15:38:19

标签: javascript undefined setinterval

我遇到了问题,因为此deltaSec变量始终在内部重置:

if(typeof deltaSec === "undefined"){...}

您甚至可以看到,甚至试图解析条件中的整个属性,以保证其为“数字”类型。

这个条件验证deltaSec类型是否为“ number”是我开始发现问题之前的第一个条件(typeof deltaSec === "undefined")“ else”。

timeLineUpdater = setInterval(function (){
    var arrayTd = document.getElementsByClassName("someclass");
    if(typeof constructionTime === "undefined"){
        var constructionTime = document.getElementById("elementId").value;
    }
    if(typeof deltaSec == "number"){
        console.log(typeof deltaSec);
        if(deltaSec>0){
            deltaSec--;
        } else {
            deltaSec = deltaSec;
        }
    }
    if(typeof deltaSec === "undefined"){
        console.log(typeof deltaSec);
        var deltaSec = parseInt(60 - parseInt(constructionTime.split(":")[2]));
    }
    console.log(deltaSec);
    console.log(typeof deltaSec);
    if(deltaSec == 0){
        //do something
        deltaSec = 60;
    }
},1000);

正在寻找解决方案:

if(deltaSec>0){
    deltaSec--;
} else {                  //this
    deltaSec = deltaSec;
}

控制台实际结果:

无限重复:

undefined
x //started value
number

2 个答案:

答案 0 :(得分:2)

对于您的代码示例,这是正确的JS和预期行为。

在词法块中任何地方(在这种情况下,var)中以function() {}开头的变量声明都将提升到该块的开头。您可以通过以下方法使自己确信(观看控制台):

setInterval(function() {
  console.log("Before assignment");
  console.log(globalElement);
  var globalElement = "bar";
  console.log(globalElement);
}, 1000);

您的功能实际上等效于以下内容:

timeLineUpdater = setInterval(function (){
    var deltaSec;
    var arrayTd = document.getElementsByClassName("someclass");
    if(typeof constructionTime === "undefined"){
        var constructionTime = document.getElementById("elementId").value;
    }
    if(typeof deltaSec == "number"){
        console.log(typeof deltaSec);
        if(deltaSec>0){
            deltaSec--;
        } else {
            deltaSec = deltaSec;
        }
    }
    if(typeof deltaSec === "undefined"){
        console.log(typeof deltaSec);
        deltaSec = parseInt(60 - parseInt(constructionTime.split(":")[2]));
    }
    console.log(deltaSec);
    console.log(typeof deltaSec);
    if(deltaSec == 0){
        //do something
        deltaSec = 60;
    }
},1000);

结果是,在第一个if语句上,deltaSec是未定义的(因为它在该函数的更下方位置被指定为局部变量,并且解释器已经保留了该变量)。结果,undefined if检查被处理,这将deltaSec设置为整数。

您的下一个console.log(在if语句之后)然后将其打印为整数。

在下一个循环中,此行为重新开始,因为变量没有在其他地方持续存在。

如果要摆脱这种行为,请将var放在deltaSec分配前面。

答案 1 :(得分:0)

我认为您应该在setInterval处理函数的范围之外声明constructionTimedeltaSec。代码发生的事情是,您在if子句的范围内声明了变量,但在该范围之外不可见。顺便说一句,为什么在else子句中使用deltaSec = deltaSec;。那什么也没做。我认为您的代码应该看起来像这样,尽管我不确定您要在这里做什么。

var deltaSec;
var constructionTime;
var timeLineUpdater = setInterval(function (){
    var arrayTd = document.getElementsByClassName("someclass");
    constructionTime = document.getElementById("elementId").value;
    deltaSec = 60 - parseInt(constructionTime.split(":")[2]);
    console.log(deltaSec);
    console.log(typeof deltaSec);
    if(deltaSec == 0){
        //do something
        deltaSec = 60;
    }
},1000);