You are already familiar with the for and while loops. I’m going to tell you two ways to break the loop and one way to skip an iteration.

Interrupting the loop with return

When the keyword return is encountered in the function, it is interrupted and some value is returned to the place where the function was called.

  • return 1 - returns the number 1
  • return 'hello' - returns the string hello
  • empty return - returns undefined

You don’t have to put a return at the end of the function. You can easily check some condition in the loop and if it is truthy, return the result immediately.

This can be helpful if you are looking for something in the array.

const findValueInArray = (arr, n) => {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === n) {
      return i;
    }
  }
  return -1;
}

The findValueInArray function will return the position of the element n in the array arr or -1 if it is not found. The function will stop and the loop will break as soon as we find a match and we will not analyze the remaining elements of the array.

Interrupting the loop with break

Sometimes you don’t need to interrupt the execution of a function, but you need to stop the loop. Then instead of return, you need to use break. The loop will break, but the function will continue its execution.

export const askNameAndGreet = () => {
  let name;
  while (true) {
    name = readlineSync.question('Please enter your name:');
    if (name && name.length > 2) {
      break;
    } else {
      console.log('Your name should have at least 3 characters in it');
    }
  }
  console.log(`Hello, ${name}!`);
}

We’ve slightly rewritten the askNameAndGreet function from one of the opening chapters. The user will repeatedly receive a question about their name until they enter a string of three characters or more. As soon as this happens, the (name && name.length > 2) condition inside the if will become true and the break command will be executed. The loop will break and the command console.log will display a welcome message on the screen.

Skip one iteration with continue

If we need to skip only the current loop iteration, but not interrupt it completely, then we need the continue command. For example, we have a loop that prints numbers from 0 to 9 to the screen.

for (let i = 0; i < 10; i++) {
  console.log(i);
}

But we would like to improve it a little and not execute the command console.log for the number 5.

for (let i = 0; i < 10; i++) {
  if (i === 5) {
    continue;
  }
  console.log(i);
}

After the condition inside the if becomes true, continue will be executed and we will immediately go to the next iteration of the loop. console.log will print all the values of i except 5.

Looping through array elements using for...of

If we use a loop to analyze the elements of an array and we don’t care about their index (position in the array), then we can use the for...of loop.

This is what the function would look like, which prints the values of all elements of the array to the screen.

const printArrayItems = (arr) => {
  for (const item of arr) {
    console.log(item);
  }
}

As you can see, we no longer have a loop counter. The loop will keep going until we iterate over all the elements of the arr array.

In for...of, you can also use a string instead of an array. In this case, you will iterate over all of its symbols.

Looping through object keys using for...in

If we need to iterate over the values of all keys (fields) of an object, we can use the for...in loop. This loop is similar to for...of, but instead of array elements, we have the keys of the object.

const printObjectKeys = (obj) => {
  for (const key in obj) {
    console.log(key);
  }
}

If we pass the object user = {name: 'Jack', email: '[email protected]'} to such a function, then the strings name and email will be displayed on the screen.

By the way, you can access the fields of an object not only with the dot ., but also with the square brackets []. Look:

const user = { name: 'Jack', email: '[email protected]' };

console.log(user['name']);  // Jack
console.log(user.name);     // Jack

In both cases, we’ll get the value of the name field of the user object.

Square brackets for accessing the fields of an object can be useful when we don’t exactly know which fields are in the object.

For example, you can write a universal function that will display the names of all fields of an object and their values.

const printObjectKeysAndValues = (obj) => {
  for (const key in obj) {
    console.log (`${key}: ${obj[key]}`);
  }
}

If we pass our Jack to the printObjectKeysAndValues function, we will see on the screen:

name: Jack
email: [email protected]

But we can use a different object as well. For example, Jack’s dog.

const pet = { type: 'Dog', name: 'Rex', age: 5 };

printObjectKeysAndValues(pet);

And we will see the following output:

type: Dog
name: Rex
age: 5

Even though the pet object has more fields and they are named differently, we were able to display them all using the same printObjectKeysAndValues function. If we used a dot - . to access the fields, and not square brackets - [], we would have failed, because we didn’t know in advance what fields will be in the object that was passed into the function.

FAQ

— Wow, how do I remember all this? — Solving practical tasks in VSCode! How else would you do it :)?