4

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.

Zoe - Save the data dump
28.4k22 gold badges130 silver badges163 bronze badges
asked Feb 21, 2014 at 22:30
5
  • 3
    i<index.length - you understand i is being incremented on every iteration (because of i++), and index.length is technically decrementing on every iteration (because of index.pop())....right? That means at some point sooner than you expected, i<index.length will 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 store index.length once at the beginning. And by the way, this isn't something special with JavaScript. I'm pretty sure this would've happened in any language Commented Feb 21, 2014 at 22:33
  • 1
    As everyone has already commented, the value of index.length changes 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 array index = [];? Commented Feb 21, 2014 at 22:36
  • 1
    FWIW, the third expression in 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 to for(var i=index.length; i--; ) Commented Feb 21, 2014 at 22:39
  • @straker You have a good point there. pop() was strangely the first thing that came to mind. Otherwise I see no reason why not to do that. Commented Feb 21, 2014 at 22:49
  • 1
    Using a while for this may be simpler while (array.length) { array.pop(); } and of course there is array.length = 0. Just some additional thoughts. :) Commented Feb 21, 2014 at 22:56

3 Answers 3

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+';'); }
answered Feb 21, 2014 at 22:36
Sign up to request clarification or add additional context in comments.

3 Comments

You can also declare the length inside the for loop: for (var i = 0, length = index.length; i < length; i++)
This makes me feel like a bit of an idiot. I should have seen this. Thankfully these lapses don't happen very often. Thanks again for answering, everyone.
@straker That doesn't really change much. Both 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)
1

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.

answered Feb 21, 2014 at 22:34

6 Comments

Real stupid of me thanks. To my saving grace though, I thought that the first three statements inside a for loop were only executed once, not every time the loop, well, loops.
@Lexica98: Then how could the comparison and increment of i work? ;)
@Lexica98 I think you need to read here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
maybe I should elaborate: I thought that once the first three statements were defined in the for loop, the interpreter would not look for index.length dynamically, but instead would take the length as whatever the length was at the time, which I see is untrue. I did think that i would increment, but I thought that the other statements were kind of set in stone until the loop ended.
Absolutely, thanks. Initialization, condition, final expression. Got it!
|
0

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+';'); }
answered Feb 21, 2014 at 22:38

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.