2012-04-07 162 views
0

方法constructBuilder()不应该无限变化,因为它设置为只循环10次,并且data.length的值永远不会改变。为什么这个javascript无限循环?

这个循环&方法infact完美地工作,直到我调用循环内的另一个方法。

当我把这个循环里面的方法getOptions(type)i变化,价值非常奇怪,并始终遵循以下模式:

1st run: i=0 
2nd run: i=1 
3rd run: i=3 
4th run: i=5 
5th run: i=6 
6th run: i=4 
7th run: i=4 
8th run: i=4 
nth run: i=4 

i值卡在4,不递增,循环无限运行!

为什么会发生这种情况?

下面是代码:

var data = [["Text Array", "Some more text", "btnText", "btn2text"], 
      ["Text2", "2: more text", "btnText2", "btn2text2"], 
      ... 
      ]; 

var products, order; 

function initialise() { 
    products = loadProducts(); 
    order = new Order(); 
    constructBuilder(); 
} 

function constructBuilder() { 
    var qb_boxes_innerHTML = ""; 
    for (i=0; i<data.length; i++) { 
     alert("i="+i + "; data length="+data.length); 
     var box_innerHTML = "<table width=100% height=100% cellpadding=0; cellspacing=0; border=0>"; 
     box_innerHTML += "<tr><td width=100% height=\"50px\">" + data[i][0] + "</td></tr>"; 
     box_innerHTML += "<tr><td width=100% class=\"scroll\" valign=\"top\">" + data[i][1] + getOptions(i) + "</td></tr>"; 
     box_innerHTML += "<tr><td width=100% height=\"50px\" align=\"right\" valign=\"middle\"><form action=\"javascript:next();\"><input type=\"button\" value=\"" 
        + data[i][2] + "\" onClick=\"prev();\"/><input id=\"continueBtn\" type=\"submit\" value=\"" 
        + data[i][3] + "\" disabled/></form></td></tr>"; 
     box_innerHTML += "</table>"; 
     qb_boxes_innerHTML += "<div id=\"qb_box" + i + "\" class=\"qb_box\" style=\"visibility: hidden;\">" + box_innerHTML + "</div>"; 
    } 
    document.getElementById("qb_boxes").innerHTML = qb_boxes_innerHTML; 
    document.getElementById("qb_box0").style.visibility = ""; 
} 
function getOptions(type) { 
    var optionsList = getProducts(products, type); 
    var options_html = ""; 
    for (i=0; i<optionsList.length; i++) { 
     options_html += "<input id=\"check"+type+"_"+i+"\" type=\"checkbox\"/>" + optionsList[i].name + "<BR/>"; 
    } 
    return options_html; 
} 

function getProducts(productList, type) { 
     var productsOfType = new Array(); 
     for (i=0; i<productList.length; i++) { 
     if (productList[i].type == type) 
      productsOfType.push(productList[i]); 
     } 
     return productsOfType; 
} 

如果您需要任何更多的信息,请评论。

感谢您的期待。

回答

6

通过使用i而不是var您实际上使用的是全局变量window.i。改变你的功能,使i被声明为局部变量:

function constructBuilder() { 
    var qb_boxes_innerHTML = ""; 
    var i; 
    /* ... */ 
} 
+0

啊,是的,隐含的全局变量的恐怖...... – 2012-04-07 20:01:46

+1

''严格使用';':)的喜悦。 – Zeta 2012-04-07 20:03:27

+0

@泽塔谢谢,就是这样。当它可用时,我会接受答案。 – Ozzy 2012-04-07 20:04:09

5

i变量是全球性的,所以每个函数内环路共享相同的计数器。在for循环声明(for(var i = 0; ...)中使用var关键字来声明局部变量。

+0

谢谢,我提高了你的答案,但泽塔击败你约30秒:) – Ozzy 2012-04-07 20:07:05

0

问题是在constructBuilder()中调用getOptions(i)。当你在全球宣布“我”时,我的价值在你的案例中一直保持变回4