For...in проти for...of в JavaScript
for...in vs for...of
Обидва for...in та for...of є конструкціями циклів, але вони ітерують по різних речах і виконують різні цілі.
for...in
Ітерує по перераховуваних ключах властивостей (рядках) об'єкта:
javascript
const user = { name: "Alice", age: 25, city: "Kyiv" };
for (const key in user) {
console.log(key, user[key]);
}
// "name" "Alice"
// "age" 25
// "city" "Kyiv"for...in з масивами (Уникайте!)
javascript
const arr = ["a", "b", "c"];
// ❌ Ітерує по індексах як РЯДКАХ, включає успадковані властивості
for (const index in arr) {
console.log(index, typeof index); // "0" string, "1" string, "2" string
}
// ✅ Використовуйте for...of для масивів
for (const value of arr) {
console.log(value); // "a", "b", "c"
}Проблема з прототипом
javascript
const parent = { inherited: true };
const child = Object.create(parent);
child.own = "property";
for (const key in child) {
console.log(key); // "own", "inherited" (включає успадковане!)
}
// Виправлення: фільтруйте за допомогою hasOwnProperty
for (const key in child) {
if (child.hasOwnProperty(key)) {
console.log(key); // "own" тільки
}
}for...of
Ітерує по ітерованих значеннях (елементи масивів, рядків, Maps, Sets тощо):
javascript
// Масиви
for (const value of [1, 2, 3]) {
console.log(value); // 1, 2, 3
}
// Рядки
for (const char of "Hello") {
console.log(char); // "H", "e", "l", "l", "o"
}
// Maps
const map = new Map([["a", 1], ["b", 2]]);
for (const [key, value] of map) {
console.log(key, value); // "a" 1, "b" 2
}
// Sets
const set = new Set([1, 2, 3]);
for (const value of set) {
console.log(value); // 1, 2, 3
}for...of з об'єктами (Не безпосередньо!)
javascript
const obj = { a: 1, b: 2, c: 3 };
// ❌ Об'єкти НЕ є ітерованими
for (const value of obj) {} // TypeError!
// ✅ Використовуйте Object.entries(), Object.keys() або Object.values()
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}Таблиця порівняння
| Особливість | for...in | for...of |
|---|---|---|
| Ітерує по | Ключах властивостей | Ітерованих значеннях |
| Працює з об'єктами | Так | Ні (не ітерований) |
| Працює з масивами | Так (але уникайте) | Так ✅ |
| Працює з рядками | Ні (використовуйте for...of) | Так ✅ |
| Працює з Map/Set | Ні | Так ✅ |
| Включає успадковані | Так (ланцюг прототипів) | Ні |
| Повертає | Рядкові ключі | Актуальні значення |
Резюме
javascript
// ✅ for...in — для ОБ'ЄКТІВ
for (const key in object) { }
// ✅ for...of — для МАСИВІВ, рядків, Maps, Sets
for (const value of iterable) { }
// ✅ Також розгляньте:
Object.keys(obj).forEach(key => {});
Object.entries(obj).forEach(([k, v]) => {});
array.forEach((item, index) => {});Важливо:
Використовуйте for...in для об'єктів (з перевіркою hasOwnProperty). Використовуйте for...of для масивів та ітерованих об'єктів. Ніколи не використовуйте for...in на масивах — він ітерує по рядкових індексах та включає успадковані властивості.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.