我有一个循环,它使用不同的超时间隔使用不同的参数调用一个函数三次:
<script type="text/javascript">
var myArray = [];
for (i=0; i<3; i++) {
myArray[i] = [];
myArray[i]['second'] = (1+i)*3000;
myArray[i]['valeur'] = i+i;
setTimeout(function() {
otherfunction(myArray[i]['valeur']);
}, myArray[i]['second']);
}
function otherfunction(data1) {
console.log(data1);
}
</script>
脚本正确调用了 otherfunction(),但存在错误:
未捕获的类型错误:无法读取未定义的属性"valeur"
我该如何解决这个问题。看起来像是关于变量范围的问题。
更改它,如下所示:
for (i=0; i<3; i++)
{
myArray[i] = new Array();
myArray[i]['second'] = (1+i)*3000;
myArray[i]['valeur'] = i+i;
var timeoutCallback = (function(valeur){
return function(){
otherfunction(valeur);
}
})(myArray[i]['valeur']);
setTimeout(timeoutCallback, myArray[i]['second']);
}
这里的重点是使用 JavaScript closures
将变量的当前值保留在作用域中,用于类似回调的函数。
如您所见,我们这里有 2 个嵌套函数,第一个创建一个安全范围来保持您的当前值 myArray[i]['valeur']
,这完全取决于变量 i
,在您的 for 循环中没有固定值。
有关查看此问题的更多信息,这是有史以来最有价值的答案:
JavaScript 闭包是如何工作的?
这是因为在超时函数中
i
变量已经是 3,而你的数组长度是 3,所以 myArray[3] 是未定义的。您需要确保传递给 setTimeout 的函数在正确的值上有一个闭包。
这将起作用:
var myArray = new Array();
for (i=0; i<3; i++)
{
myArray[i] = new Array();
myArray[i]['second'] = (1+i)*3000;
myArray[i]['valeur'] = i+i;
(function(val){
setTimeout(function()
{
otherfunction(val);
},myArray[i]['second']);
})(myArray[i]['valeur']);
}
function otherfunction(data1)
{
console.log(data1);
}