JavaScript循环中的预递减运算符导致堆栈溢出

时间:2015-11-04 08:33:23

标签: javascript arrays while-loop infinite-loop

最近我经历了一些JavaScript代码,并且在多个地方他们使用while循环来迭代数组。他们这样做的方式是

var i = dataArray.length;
while ( i-- ) {
   // iterating over the array.
}

我们知道这里的后递减运算符首先会在调用时提供值,然后将其减少一个。所以在这种情况下,对于第一次迭代,如果数组长度为10,则while调用检查i为10,并且我们在循环内得到i的值为9.这继续直到我达到值0然后我们退出循环。准确地说,我们正在以相反的方式迭代数组。

这很好。我真正困惑的地方是当我写一个预减量运算符时,while循环会永远运行,从而导致堆栈溢出。

var i = dataArray.length;
while ( --i ){
   // This loop would run forever.
}

为什么会这样?不会--i会导致i在某个时间点触及0值并打破循环吗?

2 个答案:

答案 0 :(得分:3)

仅当dataArray为空时才会出现这种情况。在那种情况下,i = dataArray.length变为零。然后,当您进入while循环时,i会预先递减为-1。由于所有非零数字都计算为true,因此循环会一直持续下去。

但是,如果数组中有任何元素,则不会发生这种情况,循环将终止。此代码将说明效果,而无需任何操作:

function loop(x) {
   var i = x.length;
   while ( --i ) {
       console.log(i);
       if(i == -5) break; //Break after a while so we avoid an endless loop.
   }
}

loop([]);
loop([1,1,1]);

第一个电话的输出为-1, -2, -3, -4, -5,第二个电话的输出为2, 1

JSFiddle

答案 1 :(得分:0)

While循环的理想方式。

while(condition){
    // Your code
    // iterator update (i++/i--)
}

为什么你循环停止? JavaScript将0视为false,并在达到0时停止。

也无法分辨为什么预定义会永远运行。这可能是因为i永远不会达到0;

循环模拟

var data = [];

function createArray(){
	for (var i=0; i<10; i++){
    	data.push(i);
    }
}

function preDecrementLoop(){
    var i = data.length;
    while(--i){
    	console.log(i);
    }
}

function postDecrementLoop(){
    var i = data.length;
    while(i--){
    	console.log(i);
    }
}

(function(){
    createArray();
    console.log("pre decrement");
    preDecrementLoop();
    console.log("post decrement");
    postDecrementLoop();
})()

注意:--i将跳过0的循环,因为0被视为false while (0) == while (false)