我有一个循环使用不同的超时间隔调用具有不同参数的函数三次:
<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(),但出现错误:
未捕获的TypeError:无法读取未定义的属性'valeur'
我该如何解决这个问题。看起来像是有关变量范围的问题。
答案 0 :(得分:4)
改变它:
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循环中没有有一个固定的值。
有关查看此问题的详细信息,这是有史以来最有价值的答案:
答案 1 :(得分:0)
那是因为在超时功能中
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);
}