Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Map: похож на объект или на массив?
Map — это встроенный объект в JavaScript, который похож на объект, но это не совсем объект. И не совсем массив. Map — это уникальная структура данных, которая сочетает удобство объекта с функциональностью, похожей на массив.
Что такое Map?
Map — это коллекция key-value пар (как объект), но с ключевыми отличиями:
const map = new Map();
map.set('name', 'John');
map.set('age', 30);
map.set(1, 'number key');
map.set({ id: 1 }, 'object key');
console.log(map.get('name')); // 'John'
console.log(map.size); // 4
Map vs Object
Объект:
const obj = {};
obj['name'] = 'John';
obj['age'] = 30;
obj[1] = 'number'; // ключ автоматически станет '1' (string)
console.log(Object.keys(obj)); // ['1', 'name', 'age']
Map:
const map = new Map();
map.set('name', 'John');
map.set('age', 30);
map.set(1, 'number'); // ключ остаётся 1 (number)
console.log(map.keys()); // MapIterator [1, 'name', 'age']
Практические различия
1. Ключи могут быть любого типа (в объекте только строки или символы)
// Объект — ключ преобразуется в строку
const obj = {};
obj[1] = 'one';
obj[1.5] = 'one point five';
obj[true] = 'boolean';
obj[{ id: 1 }] = 'object';
console.log(Object.keys(obj));
// ['1', '1.5', 'true', '[object Object]']
// Объект ломается!
// Map — ключи сохраняют тип
const map = new Map();
map.set(1, 'one');
map.set(1.5, 'one point five');
map.set(true, 'boolean');
map.set({ id: 1 }, 'object');
for (let [key, value] of map) {
console.log(typeof key, key, value);
}
// number 1 'one'
// number 1.5 'one point five'
// boolean true 'boolean'
// object { id: 1 } 'object'
2. Встроенные методы
// Object — нужны манипуляции
const obj = { name: 'John', age: 30 };
Object.keys(obj); // ['name', 'age']
Object.values(obj); // ['John', 30]
Object.entries(obj); // [['name', 'John'], ['age', 30]]
// Map — встроенные методы
const map = new Map([['name', 'John'], ['age', 30]]);
map.keys(); // MapIterator ['name', 'age']
map.values(); // MapIterator ['John', 30]
map.entries(); // MapIterator [['name', 'John'], ['age', 30]]
map.size; // 2
map.has('name'); // true
map.get('name'); // 'John'
map.delete('name'); // true
map.clear(); // удаляет всё
3. Производительность
// Map быстрее для частых операций добавления/удаления
const iterations = 1000000;
// Object
const obj = {};
console.time('Object');
for (let i = 0; i < iterations; i++) {
obj[i] = i;
}
console.timeEnd('Object'); // медленнее
// Map
const map = new Map();
console.time('Map');
for (let i = 0; i < iterations; i++) {
map.set(i, i);
}
console.timeEnd('Map'); // быстрее
4. Итерация
// Object — нужно преобразовать
const obj = { name: 'John', age: 30 };
for (let [key, value] of Object.entries(obj)) {
console.log(key, value);
}
// Map — встроенная итерация
const map = new Map([['name', 'John'], ['age', 30]]);
for (let [key, value] of map) {
console.log(key, value);
}
// Map работает с forEach
map.forEach((value, key) => {
console.log(key, value);
});
Map похож на массив?
Да, если смотреть на итерацию:
// Как массив можно переобойти
const map = new Map([['a', 1], ['b', 2]]);
// For of (как с массивом)
for (let entry of map) {
console.log(entry); // ['a', 1], ['b', 2]
}
// Можно развернуть в массив
const arr = Array.from(map); // [['a', 1], ['b', 2]]
const pairs = [...map]; // то же самое
Но это не настоящий массив:
const map = new Map();
map.set('a', 1);
map[0]; // undefined — индексация не работает
map.length; // undefined — нет свойства length
map.push; // undefined — нет метода push
Array.isArray(map); // false
Когда использовать Map?
Map — используй для:
// 1. Когда ключи не строки
const cache = new Map();
const user = { id: 1 };
cache.set(user, { name: 'John' });
// 2. Когда нужна частая добавление/удаление
const activeUsers = new Map();
function addUser(id) {
activeUsers.set(id, { joined: Date.now() });
}
function removeUser(id) {
activeUsers.delete(id);
}
// 3. Когда нужно сохранить порядок insertion
const order = new Map();
order.set('first', 1);
order.set('second', 2);
for (let key of order.keys()) {
console.log(key); // в порядке добавления
}
// 4. WeakMap для приватных данных (в классах)
const privateData = new WeakMap();
class User {
constructor(name) {
privateData.set(this, { secret: 'password' });
}
}
Object — используй для:
// 1. Обычные данные и конфигурация
const config = { port: 3000, host: 'localhost' };
// 2. JSON (тесно связано с объектами)
const json = JSON.stringify(config);
const parsed = JSON.parse(json);
// 3. Когда нужны методы (прототипное наследование)
const user = {
name: 'John',
getName() { return this.name; }
};
Set — аналог массива уникальных значений
Есть также Set — похож на массив, но без дубликатов:
const set = new Set([1, 2, 2, 3, 3]);
set.size; // 3
set.has(2); // true
set.delete(2); // true
for (let value of set) {
console.log(value); // 1, 3
}
На собеседовании
Краткий ответ: Map похож на объект (key-value пары), но с ключевыми отличиями: ключи могут быть любого типа, встроены методы как set(), get(), has(), delete(), и есть свойство size. Map итерируется как массив, но это не настоящий массив.
Развёрнутый ответ: Map — это гибрид между объектом и массивом. Как объект: хранит пары key-value. Как массив: итерируется, имеет методы forEach и size. Главное отличие от объекта: ключи сохраняют свой тип (не преобразуются в строки), есть встроенные методы delete() и clear(), и Map быстрее для операций добавления/удаления. Используй Map когда ключи не строки, нужна частая добавление/удаление, или когда нужно сохранить порядок insertion. Set — аналог Map, но для уникальных значений без ключей.