setInterval调用带有未定义参数的函数

时间:2016-05-01 12:19:58

标签: javascript jquery

此问题已标记为已通过上面提供的链接回答。但是,我已经阅读了这个答案,它只回答了如何在for循环中使用setInterval。在该解决方案中没有传递给参数的函数被调用,这就是我的情况,所以我无法使用它来修复我的情况。

我对编程很新,所以我会尽力描述。在setInterval中,我将一个参数传递给setInterval调用的函数toggleClusters。调试器将参数显示为正确。它是对包含地图标记对象的对象文字的数组位置的引用。我似乎误解了什么值保持不变以及使用setInterval时没有什么,因为调试器显示正确的对象文字作为arg传递,但是当调用该函数时,调试器显示应该是的obj以未定义的方式传递。是否在调用函数时不再存在此传递的值?

function setClusterAnimations() {
    for (var i = 0; i < clusters.length; i++) {
        //intervalNames stores handle references for stopping any setInterval instances created
        intervalNames.push(setInterval(function () {
        //clusters[i] will hold an object literal containing marker objects    
        toggleClusters(clusters[i]);
        }, 1000));
    }
}
//cObj is coming back as undefined in debugger and bombing
function toggleClusters(cObj) {
    var propCount = Object.keys(cObj).length;
    for (var prop in cObj){
        if (prop.getZIndex() < 200 || prop.getZIndex() == 200 + propCount) {
            prop.setZIndex(200);
        }
        else {
            prop.setZindex(prop.getZIndex() + 1)
        }
    } 
}  

2 个答案:

答案 0 :(得分:3)

这通常是与setInterval()一样的异步调用的问题。您可以通过不同的方式解决此问题,其中一种方法是使用bind()

for (var i = 0; i < clusters.length; i++) {
    //intervalNames stores handle references for stopping any setInterval instances created
    intervalNames.push(setInterval(function (i) {
    //clusters[i] will hold an object literal containing marker objects    
        toggleClusters(clusters[i]);
    }.bind(null, i), 1000));
}

toggleClusters(clusters[i])语句只会在你的循环结束时执行,此时i将超出正确的范围(它将是clusters.length)。使用bind(),并且主要使用函数参数i,您可以在回调函数的范围内创建一个单独的变量,该变量在您执行bind()时获取其值。 i独立于原始i,并保留您通过bind()提供的值。

答案 1 :(得分:1)

那是因为你的&#34;我&#34;在作为setInverval的参数传递的函数中未捕获变量。 因此,当调用此函数时,i始终等于clusters.length。

考虑以下两段代码之间的差异:

 var arr = [1, 2, 3];

var broken = function() {
    for(var i = 0; i < arr.length; ++i) {
      setInterval(function() {
        console.log("broken: " + arr[i]);
      }, 1000);
      // logs broken: undefined
  }
};

var fixed = function() {
    for(var i = 0; i < arr.length; ++i) {
    setInterval((function(k) {
        return function() {
        console.log("fixed: " + arr[k]);
      }
    }(i)), 1000); // i is captured here
  }
};