Loop through an array in JavaScript

4,695,184

Solution 1

Three main options:

  1. for (var i = 0; i < xs.length; i++) { console.log(xs[i]); }
  2. xs.forEach((x, i) => console.log(x));
  3. for (const x of xs) { console.log(x); }

Detailed examples are below.


1. Sequential for loop:

var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
    console.log(myStringArray[i]);
    //Do something
}

Pros

  • Works on every environment
  • You can use break and continue flow control statements

Cons

  • Too verbose
  • Imperative
  • Easy to have off-by-one errors (sometimes also called a fence post error)

2. Array.prototype.forEach:

The ES5 specification introduced a lot of beneficial array methods. One of them, the Array.prototype.forEach, gave us a concise way to iterate over an array:

const array = ["one", "two", "three"]
array.forEach(function (item, index) {
  console.log(item, index);
});

Being almost ten years as the time of writing that the ES5 specification was released (Dec. 2009), it has been implemented by nearly all modern engines in the desktop, server, and mobile environments, so it's safe to use them.

And with the ES6 arrow function syntax, it's even more succinct:

array.forEach(item => console.log(item));

Arrow functions are also widely implemented unless you plan to support ancient platforms (e.g., Internet Explorer 11); you are also safe to go.

Pros

  • Very short and succinct.
  • Declarative

Cons

  • Cannot use break / continue

Normally, you can replace the need to break out of imperative loops by filtering the array elements before iterating them, for example:

array.filter(item => item.condition < 10)
     .forEach(item => console.log(item))

Keep in mind if you are iterating an array to build another array from it, you should use map. I've seen this anti-pattern so many times.

Anti-pattern:

const numbers = [1,2,3,4,5], doubled = [];

numbers.forEach((n, i) => { doubled[i] = n * 2 });

Proper use case of map:

const numbers = [1,2,3,4,5];
const doubled = numbers.map(n => n * 2);

console.log(doubled);

Also, if you are trying to reduce the array to a value, for example, you want to sum an array of numbers, you should use the reduce method.

Anti-pattern:

const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });

Proper use of reduce:

const numbers = [1,2,3,4,5];
const sum = numbers.reduce((total, n) => total + n, 0);

console.log(sum);

3. ES6 for-of statement:

The ES6 standard introduces the concept of iterable objects and defines a new construct for traversing data, the for...of statement.

This statement works for any kind of iterable object and also for generators (any object that has a \[Symbol.iterator\] property).

Array objects are by definition built-in iterables in ES6, so you can use this statement on them:

let colors = ['red', 'green', 'blue'];
for (const color of colors){
    console.log(color);
}

Pros

  • It can iterate over a large variety of objects.
  • Can use normal flow control statements (break / continue).
  • Useful to iterate serially asynchronous values.

Cons

Do not use for...in

@zipcodeman suggests the use of the for...in statement, but for iterating arrays for-in should be avoided, that statement is meant to enumerate object properties.

It shouldn't be used for array-like objects because:

  • The order of iteration is not guaranteed; the array indexes may not be visited in numeric order.
  • Inherited properties are also enumerated.

The second point is that it can give you a lot of problems, for example, if you extend the Array.prototype object to include a method there, that property will also be enumerated.

For example:

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
    console.log(array[i]);
}

The above code will console log "a", "b", "c", and "foo!".

That can be particularly a problem if you use some library that relies heavily on native prototypes augmentation (such as MooTools).

The for-in statement, as I said before, is there to enumerate object properties, for example:

var obj = {
    "a": 1,
    "b": 2,
    "c": 3
};

for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) {
        // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
        console.log("prop: " + prop + " value: " + obj[prop])
    }
}

In the above example, the hasOwnProperty method allows you to enumerate only own properties. That's it, only the properties that the object physically has, no inherited properties.

I would recommend you to read the following article:

Solution 2

Yes, assuming your implementation includes the for...of feature introduced in ECMAScript 2015 (the "Harmony" release)... which is a pretty safe assumption these days.

It works like this:

// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
  // ... do something with s ...
}

Or better yet, since ECMAScript 2015 also provides block-scoped variables:

// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
  // ... do something with s ...
}
// s is no longer defined here

(The variable s is different on each iteration, but can still be declared const inside the loop body as long as it isn't modified there.)

A note on sparse arrays: an array in JavaScript may not actually store as many items as reported by its length; that reported number is simply one greater than the highest index at which a value is stored. If the array holds fewer elements than indicated by its length, its said to be sparse. For example, it's perfectly legitimate to have an array with items only at indexes 3, 12, and 247; the length of such an array is reported as 248, though it is only actually storing 3 values. If you try to access an item at any other index, the array will appear to have the undefined value there. So when you want to "loop through" an array, you have a question to answer: do you want to loop over the full range indicated by its length and process undefineds for any missing elements, or do you only want to process the elements actually present? There are plenty of applications for both approaches; it just depends on what you're using the array for.

If you iterate over an array with for..of, the body of the loop is executed length times, and the loop control variable is set to undefined for any items not actually present in the array. Depending on the details of your "do something with" code, that behavior may be what you want, but if not, you should use a different approach.

Of course, some developers have no choice but to use a different approach anyway, because for whatever reason they're targeting a version of JavaScript that doesn't yet support for...of.

As long as your JavaScript implementation is compliant with the previous edition of the ECMAScript specification (which rules out, for example, versions of Internet Explorer before 9), then you can use the Array#forEach iterator method instead of a loop. In that case, you pass a function to be called on each item in the array:

var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) { 
     // ... do something with s ...
} );

Unlike for...of, .forEach only calls the function for elements that are actually present in the array. If passed our hypothetical array with three elements and a length of 248, it will only call the function three times, not 248 times. It also distinguishes between missing elements and elements that are actually set to undefined; for the latter, it will still call the function, passing undefined as the argument. If this is how you want to handle sparse arrays, .forEach may be the way to go even if your interpreter supports for...of.

The final option, which works in all versions of JavaScript, is an explicit counting loop. You simply count from 0 up to one less than the length and use the counter as an index. The basic loop looks like this:

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  s = myStringArray[i];
  // ... do something with s ...
}

One advantage of this approach is that you can choose how to handle sparse arrays; the above code will run the body of the loop the full length times, with s set to undefined for any missing elements, just like for..of. If you instead want to handle only the actually-present elements of a sparse array, like .forEach, you can add a simple in test on the index:

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  if (i in myStringArray) {
    s = myStringArray[i];
    // ... do something with s ...
  }
}

Assigning the length value to the local variable (as opposed to including the full myStringArray.length expression in the loop condition) can make a significant difference in performance since it skips a property lookup each time through; using Rhino on my machine, the speedup is 43%.

You may see the length caching done in the loop initialization clause, like this:

var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {

The explicit counting loop also means you have access to the index of each value, should you want it. The index is also passed as an extra parameter to the function you pass to forEach, so you can access it that way as well:

myStringArray.forEach( function(s, i) {
   // ... do something with s and i ...
});

for...of doesn't give you the index associated with each object, but as long as the object you're iterating over is actually an Array (for..of works for other iterable types which may not have this method), you can use the Array#entries method to change it to an array of [index, item] pairs, and then iterate over that:

for (const [i, s] of myStringArray.entries()) {
  // ... do something with s and i ...
}

The for...in syntax mentioned by others is for looping over an object's properties; since an Array in JavaScript is just an object with numeric property names (and an automatically-updated length property), you can theoretically loop over an Array with it. But the problem is that it doesn't restrict itself to the numeric property values (remember that even methods are actually just properties whose value is a closure), nor is it guaranteed to iterate over those in numeric order. Therefore, the for...in syntax should not be used for looping through Arrays.

Solution 3

You can use map, which is a functional programming technique that's also available in other languages like Python and Haskell.

[1,2,3,4].map( function(item) {
     alert(item);
})

The general syntax is:

array.map(func)

In general func would take one parameter, which is an item of the array. But in the case of JavaScript, it can take a second parameter which is the item's index, and a third parameter which is the array itself.

The return value of array.map is another array, so you can use it like this:

var x = [1,2,3,4].map( function(item) {return item * 10;});

And now x is [10,20,30,40].

You don't have to write the function inline. It could be a separate function.

var item_processor = function(item) {
      // Do something complicated to an item
}

new_list = my_list.map(item_processor);

which would be sort-of equivalent to:

 for (item in my_list) {item_processor(item);}

Except you don't get the new_list.

Solution 4

for (const s of myStringArray) {

(Directly answering your question: now you can!)

Most other answers are right, but they do not mention (as of this writing) that ECMAScript  6  2015 is bringing a new mechanism for doing iteration, the for..of loop.

This new syntax is the most elegant way to iterate an array in JavaScript (as long you don't need the iteration index).

It currently works with Firefox 13+, Chrome 37+ and it does not natively work with other browsers (see browser compatibility below). Luckily we have JavaScript compilers (such as Babel) that allow us to use next-generation features today.

It also works on Node.js (I tested it on version 0.12.0).

Iterating an array

// You could also use "let" or "const" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) {
   console.log(letter);
}

Iterating an array of objects

const band = [
  {firstName : 'John', lastName: 'Lennon'},
  {firstName : 'Paul', lastName: 'McCartney'}
];

for(const member of band){
  console.log(member.firstName + ' ' + member.lastName);
}

Iterating a generator:

(example extracted from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)

function* fibonacci() { // A generator function
  let [prev, curr] = [1, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (const n of fibonacci()) {
  console.log(n);
  // Truncate the sequence at 1000
  if (n >= 1000) {
    break;
  }
}

Compatibility table: http://kangax.github.io/compat-table/es6/#test-for..of_loops

Specification: http://wiki.ecmascript.org/doku.php?id=harmony:iterators

}

Solution 5

In JavaScript it's not advisable to loop through an Array with a for-in loop, but it's better to use a for loop such as:

for(var i=0, len=myArray.length; i < len; i++){}

It's optimized as well ("caching" the array length). If you'd like to learn more, read my post on the subject.

Share:
4,695,184
Mark Szymanski
Author by

Mark Szymanski

Updated on July 08, 2022

Comments

  • Mark Szymanski
    Mark Szymanski almost 2 years

    In Java, you can use a for loop to traverse objects in an array as follows:

    String[] myStringArray = {"Hello", "World"};
    for (String s : myStringArray) {
        // Do something
    }
    

    Can I do the same in JavaScript?

    • Mark Szymanski
      Mark Szymanski almost 14 years
      Ok, so I'm a bit confused, it's ok to use the enhanced for loop when you are accessing the objects? And use a sequential one for filling one? Is this correct?
    • Christian C. Salvadó
      Christian C. Salvadó almost 14 years
      no, it's really simple, array objects have numeric indexes, so you want to iterate over those indexes in the numeric order, a sequential loop ensures that, the enhanced for-in loop enumerates object properties, without an specific order, and it also enumerates inherited properties... for iterating over arrays sequential loops are always recommended...
    • jondavidjohn
      jondavidjohn over 12 years
    • user3167101
      user3167101 over 8 years
    • Hamed Mahmoudkhani
      Hamed Mahmoudkhani over 7 years
      Also : myStringArray.forEach(function(value, index){ console.log(index, value) }); and result will be 0 "Hello" 1 "World"
    • EscapeNetscape
      EscapeNetscape over 7 years
      jsben.ch/#/Q9oD5 <= Here a benchmark of a bunch of solutions for looping through arrays
    • Roobie Nuby
      Roobie Nuby over 5 years
      @EscapeNetscape the link has changed and is now jsben.ch/Q9oD5. To summarize, sequential for loop takes 60% of the time that for-in takes.
    • jpmc26
      jpmc26 over 5 years
      @CMS No, it's not really simple. It's really simple in every other language. It's ridiculously complex in JS, where you have in and of that can both be used and do different things. Then you also have forEach and the ugly and annoying index based looping. Every other modern language makes looping over a collection easy and straightforward with no surprises or confusion. JS could, too, but it doesn't.
    • cobrexus
      cobrexus over 3 years
      Does this answer your question? For-each over an array in JavaScript
    • Voxlinou
      Voxlinou over 2 years
      Why isn't this question answered, people have put gigantic enermy into putting a correct, formal, with pros and cons and no answer is confirmed? I don't see a single error on their answers. Please set an anwer as confirmed
  • harto
    harto almost 14 years
    That particular example is probably better implemented using Array.forEach. map is for generating a new array.
  • Christian C. Salvadó
    Christian C. Salvadó almost 14 years
    @hasen, the Array.prototype.map method is part of the ECMAScript 5th Edition Standard, is not yet available on all implementations (e.g. IE lacks of it), also for iterating over an array I think the Array.prototype.forEach method is more semantically correct... also please don't suggest the for-in statement, see my answer for more details :)
  • Chris Cooper
    Chris Cooper about 12 years
    The first example of the "while" syntax won't work if any of the array elements is falsy.
  • Kzqai
    Kzqai about 12 years
    It seems that this would run up against similar problems as other for in usages with an array object, in that prototype member variables would be caught by the for in as well.
  • Phrogz
    Phrogz almost 12 years
    Note that some interpreters (e.g. V8) will automatically cache the length of the array if the code is called enough times and it detects that the length is not modified by the loop.
  • Phrogz
    Phrogz almost 12 years
    Note that some interpreters (e.g. V8) will automatically cache the length of the array if the code is called enough times and it detects that the length is not modified by the loop. While caching the length is still nice, it may not provide a speed boost when your code is being invoked enough times to actually make a difference.
  • Gabriel
    Gabriel almost 12 years
    Thanks for the info @Phrogz it's true that there is a lot of optimizations that the VM can make, but since older browsers don't have this it would still be best practice to optimize for it since it is so cheap.
  • Christian C. Salvadó
    Christian C. Salvadó about 11 years
    Notice that with this approach the loop will stop as soon it finds a falsey value, such as an empty string, 0, false, NaN, null or undefined, even before i reaches the length, e.g.: jsfiddle.net/prvzk/1
  • Stijn de Witt
    Stijn de Witt about 11 years
    For the people that don't get what is so ingenious: The i-- expression is first evaluated and allows the loop to continue when it's not falsish... Afterwards the counter is decremented. As soon as i becomes zero it will break out of the loop as zero is a falsish value in Javascript.
  • Stijn de Witt
    Stijn de Witt about 11 years
    Agreed with Exception. Do not underestimate the impact of extra dependencies. I would advice against this except in code that is already heavily using jQuery anyway.
  • Stijn de Witt
    Stijn de Witt about 11 years
    @Gabriel: Why? Please give real-world examples showing that not caching the length is actually a performance bottleneck. I follow the 'premature optimization is the root of all evil' approach. I will fix that one loop that actually poses a problem once I encounter it...
  • Stijn de Witt
    Stijn de Witt about 11 years
    ... and this while loop is equivalent to: for (var i=0,item; item=items[i]; i++) , which takes away the need to declare the index and item variables beforehand...
  • Gabriel
    Gabriel about 11 years
    @StijndeWitt imo it is just a stylistic issue. Honestly I no longer even use for loops instead relying on underscore for things like _.each, _.map etc. to do these things. When I did write loops like this I cached the length primarily so that all my variable declaration were in one place, at the top of my function. Following my advice in this regard is inconsequential to any real world application. Premature optimization is super bad, but if optimization happens to result from stylistic decisions I don't think it actually matters.
  • danwellman
    danwellman about 11 years
    falsish? You mean falsey. Let's all stick the proper terminology to avoid confusion ;)
  • Mark Reed
    Mark Reed over 10 years
    For new discoverers of this question, I'd just like to point out Lo-Dash, a spiritual successor of Underscore's that improves upon it in many ways.
  • daniel1426
    daniel1426 about 10 years
    The loop condition could be (item=someArray[i]) !== undefined.
  • Deniz Ozger
    Deniz Ozger about 10 years
    This loop doesn't seem to follow order of items in the array.
  • molokoloco
    molokoloco about 10 years
    My test was wrong. It's correct, showing all LOOPS now. jsperf.com/native-loop-performance/16
  • Matt
    Matt almost 10 years
    for/in loops are discouraged for array enumeration, as the order of eumeration is not guaranteed, and it enumerates properties, not just array elements. For more info, see stackoverflow.com/questions/500504/…, or even the accepted answer of this question; stackoverflow.com/a/3010848/444991
  • Sambhav Sharma
    Sambhav Sharma almost 10 years
    well, thanks for the update.. and what about the situation when we don't care about the order of the array? Will this still be discouraged?
  • Matt
    Matt almost 10 years
    It'll still be discouraged because it enumerates all the properties, not just the array elements. The two posts I linked to explain this in more detail.
  • Stijn de Witt
    Stijn de Witt almost 10 years
    @bergi is right. This loop wipes out the array as it loops through it. Not what you want in most cases.
  • njzk2
    njzk2 almost 10 years
    breaks on falsey items.
  • Noz
    Noz almost 10 years
    @Gabriel I believe JavaScript already supports the map function on arrays, no need to introduce an additional lib for that.
  • Daniel Sokolowski
    Daniel Sokolowski over 9 years
    And how about using for (var i in array) if (++i) ?
  • Walter Chapilliquen - wZVanG
    Walter Chapilliquen - wZVanG almost 9 years
    Why use underscore if ECMA-262 has been added the forEach methor. The native code is always better.
  • user513951
    user513951 over 8 years
    This exact functionality is already part of Mark Reed's answer.
  • Stijn de Witt
    Stijn de Witt over 8 years
    @Noz map has only since recently enjoyed broad browser support... And of course underscore offers more than just that. But I wholeheartedly agree that if possible and not unreasonably more complex, using vanilla JS over a library is always the better option. Dependencies are bad. Try to avoid them.
  • brk
    brk over 7 years
    for...in should be avoided for Array-like objects
  • Stijn de Witt
    Stijn de Witt almost 7 years
    Update: These days, you can use Array.forEach to get much of the same effect with native arrays.
  • Michel Jung
    Michel Jung over 6 years
    You'd rather want to use .forEach() and drop the return e;
  • marpme
    marpme over 6 years
    as map implies, the function map is for mapping a certain value to something else, hence I would not suggest using that one for this certain example.
  • DarckBlezzer
    DarckBlezzer over 5 years
    is better use i = i +1 instead of i++
  • domdambrogia
    domdambrogia about 5 years
    Was it really necessary to bring jQuery or HTML into this?
  • PowerStat
    PowerStat almost 5 years
    Could be improved: Please use: ++i instead of i++, this will avoid an temporary object. So it reduces memory usage and cpu time (no allocation required)!
  • colxi
    colxi almost 5 years
    @PowerStat can you provide a link or reference about that ? I've never aheard about it, sounds interesting...
  • PowerStat
    PowerStat almost 5 years
    @colxi For such interesting things you should read the hardcore C++ stuff from Herb Sutter and Scott Meyers. The ++i vs i++ thing is from the book: Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions - I thing you could also find it on gotw.ca but can be proved for every programing language.
  • Sapphire_Brick
    Sapphire_Brick over 4 years
    Why is it better? of course, you can do that in java as well, bu he asked about a foreach loop.
  • Sapphire_Brick
    Sapphire_Brick over 4 years
    that's the Haskell-y way to do it; keep taking the first one. clever, but probably slow.
  • Sapphire_Brick
    Sapphire_Brick about 4 years
    That's not very clean compared to z.forEach(j => console.log(j));.
  • Kamil Kiełczewski
    Kamil Kiełczewski almost 4 years
    @Sapphire_Brick actually it is quite fast - here is test
  • Sapphire_Brick
    Sapphire_Brick almost 4 years
    Of course a simple program like this is fast, but how does it scale in comparison to for(...;...;...) or for(... of ...)?
  • Kamil Kiełczewski
    Kamil Kiełczewski almost 4 years
    @Sapphire_Brick don't be lazy! :) you can check it your self- I give you link (test) to tool in above comment. However for small array case (as OP uses) when you need to optimize speed you should choose solution fastest for small arrays (not for big arrays - which can be different)
  • Sapphire_Brick
    Sapphire_Brick almost 4 years
    You have make a good point. I ran your example with an array of 1000 items, and while(a.length) { console.log(a.shift()); } was about twice as fast as the for(var i = 0; i < a.length; i++) { console.log(a[i]); } version. ¯\_(ツ)_/¯
  • Kamil Kiełczewski
    Kamil Kiełczewski almost 4 years
    @Sapphire_Brick - thank you for your comment - I tink using console.log in tests is not good because it is complex system function and have big impact on run time. I check with r+=a[i].length (sum of words length) for array witch 1000 elements - and still this solution was much faster than other solution (and probaly the speed difference grow when number of elements grow...) - I'm surprised too that this solution is so fast :)
  • John Lord
    John Lord over 3 years
    your "some code" should have had an example in it. It isn't entirely clear if the variables are passed in directly or as "this" or whatever.
  • Peter Mortensen
    Peter Mortensen over 3 years
    @domdambrogia: It is a meme.
  • Peter Mortensen
    Peter Mortensen over 3 years
    Even if it does not exist in your native language, you should not leave out articles in English (the indefinite article ("a" or "an") and the definite article ("the")). See e.g. English Articles - 3 Simple Rules To Fix Common Grammar Mistakes & Errors and A, AN, THE - Articles in English.
  • Arthur S
    Arthur S over 3 years
    This isn't esoteric. Its simply unnecessary and makes an assumption that the a variable will not be used in further code.
  • Pitouli
    Pitouli about 3 years
    Careful! The benchmark is wrong, because the array is not reset between each execution. Since the shift() has emptied the array after the first execution, all the subsequent executions are indeed extremely fast :p When you correctly reset the array, it appears that this solution is the second slowest. jsbench.me/4dklq1kjef/1
  • Kamil Kiełczewski
    Kamil Kiełczewski about 3 years
    @Pitouli you are right - I rollback answer to its initial form. When I have more time then I will perform benchamarks again
  • bmaupin
    bmaupin almost 3 years
    I know this answer predates async and Promises, but I feel this is worth mentioning in any conversation pertaining to modern JavaScript: "forEach does not wait for promises. Make sure you are aware of the implications while using promises (or async functions) as forEach callback." (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…‌​)
  • Aleksandr Golovatyi
    Aleksandr Golovatyi almost 3 years
    "for" and "for in" loops create extra variable, "forEach" - create extra function context. I think the best way is "for of".
  • YesItsMe
    YesItsMe almost 3 years
    do you care to elaborate why 4 "for of" is the best over the others
  • Aleksandr Golovatyi
    Aleksandr Golovatyi almost 3 years
    It doesn't create needless variables or function context. But if you don't care about small disadvantages you can use any of them, what is more comfortable for you. @YesItsMe Thank you for the question.
  • Vic
    Vic over 2 years
    con of es6 for-of: can't get the current index
  • Alvaro Carvalho
    Alvaro Carvalho about 2 years
    @Vic you can, but it's not straightforward.
  • S. W. G.
    S. W. G. about 2 years
    What about the for(let ojb of objs) statement?
  • Scotty Jamison
    Scotty Jamison almost 2 years
    For reference, this is how to get the current index as you loop. I personally find this pretty straightforwards. for (const [i, x] of yourArray.entries()) { ... }.
  • Scotty Jamison
    Scotty Jamison almost 2 years
    For those looking at this answer and wondering whether they should choose forEach() of for-of, I would just recommend using for-of. for-of is the newer looping syntax that entirely replaces the need for forEach. There isn't anything that for-of offers that forEach does not, but the inverse isn't true.
  • Adam
    Adam almost 2 years
    I think the mentioned contra of missing "continue" is not really true, just use return inside the functions, its the equivalent. However, the missing "break" is a valid contra point.