首页 > 解决方案 > setInterval 始终将 deltaSec 的初始值显示为“未定义”

问题描述

我遇到了问题,因为这个 deltaSec 变量总是在内部被重置:

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

甚至尝试解析条件内的整个属性以尝试保证它为“数字”类型,如您所见。

(typeof deltaSec === "undefined")在我开始发现问题之前,验证 deltaSec 类型是否为“数字”的条件是第一个条件“其他”。

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

标签: javascriptundefinedsetinterval

解决方案


这是您的代码示例的正确 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未定义(因为它被指定为该函数中某个更远的地方的局部变量,并且解释器已经保留了它)。结果,undefinedif 检查被处理,它设置deltaSec为一个整数。

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

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

如果您想摆脱这种行为,请将作业var放在前面deltaSec


推荐阅读