Есть 2 типа циклов, которые мы можем использовать в JavaScript для перебора объектов и массивов: цикл for...of и цикл for...in. Разница между ними имеет решающее значение для понимания при написании эффективного и действенного кода на JavaScript.

Цикл for...of мы можем использовать для перебора итерируемых объектов, таких как: массивы и строки. Цикл обращается к каждому значению объекта по одному и выполняет блок кода внутри цикла для каждого значения.

Например, если у нас есть массив чисел, мы можем использовать цикл for...of внутри функции, которая возвращает наш массив numbers в квадрате.

const numbers = [2, 4, 6, 8, 10]

const numbersSquared = function (array) {
  results = [];
  for (let number of numbers) {
    number = number * number;
    results.push(number);
  }

  return results;
};

numbersSquared(numbers); // output: [4 , 16, 36, 64, 100] 
  • Функция numbersSquared объявлена ​​с использованием const и принимает array в качестве входного аргумента.
  • Затем мы объявляем пустой массив с именем results для хранения чисел в квадрате.
  • Используя цикл for...of, мы перебираем каждый элемент (number) из ввода array.
  • Во время каждой итерации мы возводим в квадрат number и сохраняем результат в новой переменной с именем numberSquared.
  • Затем мы помещаем каждый numberSquared в массив results, используя метод .push().
  • Наконец, мы возвращаем массив results в качестве вывода.

Теперь давайте посмотрим, что произойдет, если мы изменим цикл for...of в этой функции на цикл for...in.

const numbers = [2, 4, 6, 8, 10]

const numbersSquared = function (array) {
  results = [];
  for (let number in numbers) {
    number = number * number;
    results.push(number);
  }

  return results;
};

numbersSquared(numbers); // output: [ 0, 1, 4, 9, 16 ] 

Обратите внимание, что выходные данные при вызове функции numbersSquared изменились. Почему это?

Цикл for...in работает аналогично, но используется для перебора свойств объекта, возвращающего индекс/ключ свойства вместо значения свойства. В этом случае для каждой итерации number возвращает свой индекс, а не значение. Следовательно, когда мы умножаем number само на себя, мы возводим в квадрат индекс каждого числа.

[0] * [0] = 0
[1] * [1] = 1
[2] * [2] = 4
[3] * [3] = 9
[4] * [4] = 16 

Давайте посмотрим, как более правильно использовать цикл for...in.

Допустим, у нас есть массив объектов с именами cookie, и мы хотим вывести в консоль индекс, имя и тип каждого cookie.

const cookies = [
  { name: "🍪", type: "chocolate" },
  { name: "🍪", type: "oatmeal" },
  { name: "🥠", type: "fortune" },
  { name: "🍪", type: "peanut butter" },
];

for (let index in cookies) {
  console.log(`Cookie ${index}:`);
  for (let property in cookies[index]) {
    console.log(`- ${property}: ${cookies[index][property]}`);
  }
}

// Output: 
// Cookie 0:
// - name: 🍪
// - type: chocolate
// Cookie 1:
// - name: 🍪
// - type: oatmeal
// Cookie 2:
// - name: 🥠
// - type: fortune
// Cookie 3:
// - name: 🍪
// - type: peanut butter
  • Здесь мы использовали 2 for...in петель:
  • Первый цикл выполняет итерацию по всем объектам в массиве файлов cookie и выводит их index на консоль.
  • Второй цикл перебирает каждое свойство каждого объекта cookie в массиве cookies и записывает их в консоль. Свойства name и type

Подводя итог всему этому, мы можем использовать for...of для циклического перебора итерируемых объектов и использовать for...in для циклического просмотра свойств объекта.