I was wondering if there was anything special about javaScript's pop() function that I should know about.
My intention was to write a program that erases all of the values in an array, without actually deleting the array. My first attempt at that was this, which didn't exactly work out:
var index = [1,2,3,4,5,6,7,8,9,10];
for(var i=0;i<index.length;i++) { index.pop(); console.log(index+';'); }
// outputs this:
[1,2,3,4,5,6,7,8,9];
[1,2,3,4,5,6,7,8];
[1,2,3,4,5,6,7];
[1,2,3,4,5,6];
[1,2,3,4,5];
And then it simply stops there. Huh? Upon checking I found that the array really was [1,2,3,4,5], and not some console.log display error. Which didn't make sense.
On a hunch, I decided to decrement the for loop instead, and use it like this:
var index = [1,2,3,4,5,6,7,8,9,10];
for(var i=index.length; i--; i>0) { index.pop(); console.log(index+';'); }
// and for some reason, this works:
[1,2,3,4,5,6,7,8,9];
[1,2,3,4,5,6,7,8];
[1,2,3,4,5,6,7];
[1,2,3,4,5,6];
[1,2,3,4,5];
[1,2,3,4];
[1,2,3];
[1,2];
[1];
[];
So, why does the second example work and not the first? Seems pretty strange to me.
EDIT: I didn't know the for loop looked for index.length every time, not just the first time it was called.
3 Answers 3
The problem is that your first for loop is looking at the index.length. It is constantly changing because the array is getting smaller! So after five loops, your array is:
[1,2,3,4,5];
and i is 5, because this is the fifth loop. So the condition i<index.length comes out to 5<5, which is false. Notice that the index.length is only '5'! We've shortened the array! So, you leave the loop. If you want it to work, you'll need to store the original length in a variable so it doesn't change on you every iteration:
var original_length = index.length;
for(var i=0;i<original_length;i++) { index.pop(); console.log(index+';'); }
3 Comments
for (var i = 0, length = index.length; i < length; i++)i and length are still hoisted, and are still accessible after the loop just the same. But I agree and would do the same thing, it just shouldn't affect the code (except for the whole storing the index.length once)When you pop an item off the array the length of the array decreases, so when you've removed five elements from the array index.length is five and i is five therefore the loop condition fails.
For the second loop you only check the length of the array at the begining before you remove elements from it.
6 Comments
i work? ;)i would increment, but I thought that the other statements were kind of set in stone until the loop ended.Just to add to the comments and answer with an example.
var l = index.length
for(var i=0;i<l;i++) { index.pop(); console.log(index+';'); }
i<index.length- you understandiis being incremented on every iteration (because ofi++), andindex.lengthis technically decrementing on every iteration (because ofindex.pop())....right? That means at some point sooner than you expected,i<index.lengthwill no longer be true and the loop will exit. If you want to make sure you loop over the array the amount you're expecting, you need to storeindex.lengthonce at the beginning. And by the way, this isn't something special with JavaScript. I'm pretty sure this would've happened in any languageindex.lengthchanges every iteration. Though, if you want to delete all elements of an array but still want the variable to be an array, why not just reassign the variable to an empty arrayindex = [];?for(var i=index.length; i--; i>0)is unnecessary. The second expression is always the condition. The third expression is always executed at the end of an iteration and typically advances the loop variable. You are only making a comparison which doesn't do anything, so it's equivalent tofor(var i=index.length; i--; )whilefor this may be simplerwhile (array.length) { array.pop(); }and of course there isarray.length = 0. Just some additional thoughts. :)