Map va Set Object va Array'dan nimasi bilan farq qiladi?
Savol
Map/Set bilan oddiy Object/Array o'rtasidagi farq nimada — kalit turlari, aylanib chiqish tartibi va tez-tez qo'shish, o'chirish, qidirishdagi unumdorlik bo'yicha?
Qisqa javob
Map kalit-qiymat juftliklarini saqlaydi, bu yerda kalit istalgan tur bo'lishi mumkin (obyektlar va funksiyalar dahil), kiritish tartibini kafolatlaydi va qo'shish/o'chirish/qidirish uchun O(1) beradi. Object kalit sifatida faqat satr va simvollarni ruxsat beradi (sonlar satrlarga keltiriladi). Set — istalgan turdagi noyob qiymatlar to'plami bo'lib, mavjudlikni O(1) da tekshiradi, O(n) da ishlaydigan Array.includesdan farqli o'laroq.
Batafsil javob
Object vs Map
- Kalit turlari:
Objectning kalitlari doim satrga (yokiSymbolga) keltiriladi —obj[1]vaobj['1']bu bitta kalit.Mapda kalit obyekt, funksiya,NaN, tur keltirishsiz istalgan narsa bo'lishi mumkin. - Tartib: zamonaviy dvigatellar obyektning satr kalitlari uchun kiritish tartibini saqlaydi, lekin butun sonli satr kalitlar (
'1','2') doim raqamli tartibda birinchi bo'lib keladi — bu aniq bo'lmagan va portativ bo'lmagan xatti-harakat.Mapkalit turidan qat'i nazar, kiritish tartibini doim va kafolatli saqlaydi. - Hajm:
Objectda kalitlar sonini bilishning o'rnatilgan usuli yo'q (Object.keys(obj).length),Mapda.sizebor. - Iteratsiya:
Objectto'g'ridan-to'g'ri iteratsiyalanmaydi (for...ofObject.entriessiz ishlamaydi),MapIterableprotokolini o'z-o'zidan amalga oshiradi. - Unumdorlik:
Mapkalitlarni tez-tez qo'shish/o'chirish uchun optimallashtirilgan — dvigatellar uning uchunObjectprototipli zanjirning bir qismi bo'lishi bilan bog'liq yon effektlarsiz alohida xesh-strukturalar ishlatadi.Objectxususiyatlarni tez-tez qo'shish/o'chirishda deoptimallashishi mumkin (V8'da "dictionary mode"ga o'tish). - Prototip: oddiy
{}Object.prototypedan meros olingan xususiyatlarga ega, bu kalitlar to'qnashuviga olib kelishi mumkin ('toString','__proto__').Mapda bu muammo yo'q — bu toza saqlash joyi.
Array vs Set
- Noyoblik:
Setavtomatik ravishda dublikatlarni tashlab yuboradi,Array— yo'q, noyoblik uchun qo'lda mantiq yozish kerak. - Qidirish:
Set.has()— amortizatsiyalanganO(1)(xesh-jadval),Array.includes()/indexOf()—O(n), chiziqli o'tish. Ko'p sonli mavjudlik tekshiruvlarida farq muhim ahamiyat kasb etadi. - O'chirish:
Set.delete(value)—O(1), massivdan qiymat bo'yicha elementni o'chirishindexOf+splice, ya'niO(n)talab qiladi. - Tartib: ikkalasi ham kiritish tartibini saqlaydi.
- Indekslash:
Arrayda sonli indekslar va ko'plab metodlar bor (map,filter,reduce),Setda bu yo'q — faqatadd,delete,has,forEach,size.
Qachon nimani ishlatish: Object/Array — seriyalashtiriladigan ma'lumotlar (JSON), oddiy strukturalar uchun, bu yerda odatiy massiv metodlari kerak. Map/Set — kalitlar satr bo'lmaganda, kafolatli tartib muhim bo'lganda, mavjudlikni tez-tez tekshirish kerak bo'lganda yoki ko'p sonli qo'shish/o'chirishda unumdorlik muhim bo'lganda.
Misol
// Object faqat satr/simvol kalitlarni ruxsat beradi
const obj = {}
const keyObj = { id: 1 }
obj[keyObj] = 'value' // keyObj "[object Object]" satriga keltiriladi
obj['[object Object]'] = 'overwritten'
console.log(obj[keyObj]) // "overwritten" — to'qnashuv!
// Map istalgan turdagi kalitlarni keltirishsiz saqlaydi
const map = new Map()
const key1 = { id: 1 }
const key2 = { id: 2 }
map.set(key1, 'first')
map.set(key2, 'second')
console.log(map.get(key1)) // "first" — turli obyektlar to'qnashmaydi
console.log(map.size) // 2
// Object'dagi sonli kalitlar tartibi — kutilmagan
const weird = { b: 1, 2: 'two', a: 3, 1: 'one' }
console.log(Object.keys(weird)) // ['1', '2', 'b', 'a'] — sonlar oldinda
// Set: noyoblik va tez has()
const arr = [1, 2, 2, 3, 3, 3]
const unique = [...new Set(arr)]
console.log(unique) // [1, 2, 3]
const bigSet = new Set(Array.from({ length: 100000 }, (_, i) => i))
console.log(bigSet.has(99999)) // O(1) — bir zumda
const bigArr = Array.from({ length: 100000 }, (_, i) => i)
console.log(bigArr.includes(99999)) // O(n) — butun massiv bo'ylab o'tish
// Map obyekt/massivga va aksincha oson aylanadi
const entries = [['a', 1], ['b', 2]]
const fromEntries = new Map(entries)
console.log(Object.fromEntries(fromEntries)) // { a: 1, b: 2 }
Qo'shimcha savollar
WeakMap/WeakSetnima va ular xotirani boshqarish uchun nima bilan foydali?- Nega
JSON.stringifyMapvaSetni to'g'ridan-to'g'ri seriyalashtira olmaydi? - V8 obyektni "dictionary mode"ga qanday o'tkazadi va bu unumdorlikka qanday ta'sir qiladi?