JavaScript while 循环中的前置自减运算符导致堆栈溢出
Pre-decrement operator in JavaScript while loop causes stack overflow
最近我浏览了一些 JavaScript 代码,他们在多个地方使用 while 循环遍历数组。他们的做法是
var i = dataArray.length;
while ( i-- ) {
// iterating over the array.
}
我们知道这里的post自减运算符会先将值提供给while调用,然后将其减一。因此,在这种情况下,对于第一次迭代,如果数组长度为 10,则 while 调用会检查 i 是否为 10,并且我们在循环内得到 i 的值为 9。这一直持续到 i 达到 0 的值,然后我们退出循环。准确的说我们是在反向迭代数组。
这很好。真正让我感到困惑的是,当我编写预递减运算符时,while 循环会一直运行,导致堆栈溢出。
var i = dataArray.length;
while ( --i ){
// This loop would run forever.
}
为什么会这样?不做 --i
也会导致 i
在某个时间点达到 0 值并中断循环吗?
写While
循环的理想方式。
while(condition){
// Your code
// iterator update (i++/i--)
}
为什么循环停止? JavaScript 认为 0
为假并在达到 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 被认为是假的,while (0) == while (false)
。
仅当 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
.
最近我浏览了一些 JavaScript 代码,他们在多个地方使用 while 循环遍历数组。他们的做法是
var i = dataArray.length;
while ( i-- ) {
// iterating over the array.
}
我们知道这里的post自减运算符会先将值提供给while调用,然后将其减一。因此,在这种情况下,对于第一次迭代,如果数组长度为 10,则 while 调用会检查 i 是否为 10,并且我们在循环内得到 i 的值为 9。这一直持续到 i 达到 0 的值,然后我们退出循环。准确的说我们是在反向迭代数组。
这很好。真正让我感到困惑的是,当我编写预递减运算符时,while 循环会一直运行,导致堆栈溢出。
var i = dataArray.length;
while ( --i ){
// This loop would run forever.
}
为什么会这样?不做 --i
也会导致 i
在某个时间点达到 0 值并中断循环吗?
写While
循环的理想方式。
while(condition){
// Your code
// iterator update (i++/i--)
}
为什么循环停止? JavaScript 认为 0
为假并在达到 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 被认为是假的,while (0) == while (false)
。
仅当 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
.