JavaScript中的预减量运算符while循环导致堆栈溢出
最近,我浏览了一些JavaScript代码,在多个地方,他们使用while循环来迭代数组。他们这样做的方式是JavaScript中的预减量运算符while循环导致堆栈溢出,javascript,arrays,while-loop,infinite-loop,Javascript,Arrays,While Loop,Infinite Loop,最近,我浏览了一些JavaScript代码,在多个地方,他们使用while循环来迭代数组。他们这样做的方式是 var i = dataArray.length; while ( i-- ) { // iterating over the array. } 我们知道这里的后减量运算符将首先向while调用提供值,然后将其减少1。因此在第一次迭代中,如果数组长度为10,while调用检查i是否为10,我们得到循环中i的值为9。这个过程一直持续到i达到0,然后我们退出循环。确切地说,我们以相反
var i = dataArray.length;
while ( i-- ) {
// iterating over the array.
}
我们知道这里的后减量运算符将首先向while调用提供值,然后将其减少1。因此在第一次迭代中,如果数组长度为10,while调用检查i是否为10,我们得到循环中i的值为9。这个过程一直持续到i达到0,然后我们退出循环。确切地说,我们以相反的方式迭代数组
这很好。真正让我困惑的是,当我编写一个预减量运算符时,while循环会永远运行,导致堆栈溢出
var i = dataArray.length;
while ( --i ){
// This loop would run forever.
}
为什么会这样?不执行
--i
也会导致i
在某个时间点命中0值并打破循环?在循环时编写的理想方式
while(condition){
// Your code
// iterator update (i++/i--)
}
你为什么停下来?JavaScript将0
视为false,并在达到0时停止
也不知道为什么预减量会永远持续。这可能是因为i
从未达到0
回路模拟
var数据=[];
函数createArray(){
对于(var i=0;i理想的写入While
循环的方式
while(condition){
// Your code
// iterator update (i++/i--)
}
为什么循环停止?JavaScript将0
视为false,并在达到0时停止
也不知道为什么predecrement永远运行。这可能是因为i
从未达到0
回路模拟
var数据=[];
函数createArray(){
对于(var i=0;i只有当dataArray
为空时才会出现这种情况。在这种情况下,ni=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
.只有当dataArray
为空时才会出现这种情况。在这种情况下,ni=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
.如果数组是空的,它的值一开始是0,--i
给出-1
,这将被求值为true,所以它永远不会停止。因此在第一次迭代中,如果数组长度是10,
如果是,那么在while
循环中你在做什么?while
是i
你在while
循环上下文?无论如何,你必须为MCVEDon提供while循环来迭代数组。索引增加了复杂性-如果你只想迭代数组,它只需for(数组的var项){/*work on item*/}
或在旧浏览器中array.forEach(function(item){/*work on item*/}
@BenjaminGruenbaum-这两种方法在大型数组上的速度都非常慢。@Stephen如果您使用大型数组,您仍然需要类型化数组。另外,递减数组并“返回”不是更快-这是货物培养。在JavaScript中用迭代数组而用迭代则是货物培养-因为一些算法从中受益(比如移除元素的算法最好移动数组的较小部分)人们开始到处写它——就好像JIT编译器不知道如何优化对JNZ
指令的=x
调用for…of
目前在当前编译器中速度较慢-这很快就会改变。如果数组为空,它的值首先为0,--i
给出-1
,该值将被求值为真,因此它永远不会停止。因此,对于第一次迭代,如果数组长度为10,
如果是,您在中做什么
loop?是i
while
loop上下文中您所期望的吗?无论如何,您必须为MCVEDon提供while循环来迭代数组。索引增加了复杂性-如果您只想迭代数组,它就像for(数组的var项){/*处理项*/}
或在较旧的浏览器中array.forEach(函数)一样简单(item){/*处理item*/}
@BenjaminGruenbaum-这两种方法在大型数组上的速度都要慢得多。@Stephen如果使用大型数组,您仍然需要一个类型化数组。另外,递减数组并“返回”不是更快-这是货物培养。在JavaScript中用迭代数组而用迭代则是货物培养-因为一些算法从中受益(比如移除元素的算法最好移动数组的较小部分)人们开始到处写它——就好像JIT编译器不知道如何优化对JNZ
指令的=x
调用一样。如果(这是一个很大的如果)for…of
在当前编译器中的速度很慢——这很快就会改变。如果是这样,--i
将跳过之后的最后一个元素,而(0)
表示错误。我还建议使用forEach
对不起,我是说--I
I--does,--I
将跳过最后一个元素,因为而(0)
表示错误。我还建议使用forEach
对不起,我是说--I