Mundarija (36)
- Bu darsda
- 1. Nega bu kerak?
- 2. To'liq xarita
- 2.1 Olti bo'lim
- 2.2 Nega obj.keys() emas, Object.keys(obj)?
- 2.3 Statik metodlar va har obyektdagi metodlar
- 3. Ko'rish: qaysi metod nimani ko'radi
- 3.1 getOwnPropertyNames
- 3.2 getOwnPropertySymbols
- 3.3 Uch metod bir jadvalda
- 4. entries → map → fromEntries
- 4.1 Naqsh
- 4.2 Filtrlash va kalitlarni o'zgartirish
- 4.3 Obyektni qiymat bo'yicha tartiblash
- 5. Object.assign
- 5.1 Nima qiladi
- 5.2 Tuzoq 1: birinchi argument o'zgaradi
- 5.3 Tuzoq 2: setter'lar
- 5.4 Manbadagi getter: qiymat ko'chadi
- 6. Tekshirish: hasOwn va is
- 6.1 hasOwnProperty ning ikki muammosi
- 6.2 Object.is — eslatma
- 7. Ko'p uchraydigan xatolar
- 7.1 obj.keys() deb yozish
- 7.2 Object.assign(standart, ...) — standart buzildi
- 7.3 fromEntries ga juftlik emas, qiymat qaytarish
- 7.4 hasOwnProperty ni obyektning o'zidan chaqirish
- 7.5 Object.keys "hammasini" beradi deb o'ylash
- 8. Mashqlar
- 1-mashq (oson): Narxlarni mingga yaxlitlash
- 2-mashq (o'rta): Sozlamalarni birlashtirish
- 3-mashq (qiyin): Ikki obyekt farqi
- 4-mashq: Vazifalar qadami — noma'lum filtrdan himoya
- 9. Real ishda
- Xulosa
- Manbalar
JavaScript Object metodlari: assign, entries, fromEntries, hasOwn, is va boshqalar — to'liq sharh
Qisqacha:
Objectda 23 ta statik metod bor va ular olti guruhga bo'linadi: ko'rish (keys,entries,getOwnPropertyNames), aylantirish (fromEntries,groupBy), nusxalash (assign), tekshirish (hasOwn,is), himoya (freeze,seal) va deskriptor/prototip. Eng ko'p ishlatiladigan naqsh —Object.fromEntries(Object.entries(obj).map(...)): obyektni massivga aylantirib, massiv metodlari bilan ishlab, qaytarib obyektga yig'ish.
Bu darsda
Objectning barcha statik metodlarini olti guruhga ajratib, har biri qachon kerakligini ayta olasiz.entries→map/filter→fromEntriesnaqshi bilan obyektni o'zgartira olasiz.Object.assignva spread farqini (birinchi argument o'zgarishi, setter'lar) bilasiz.- Nega
hasOwnPropertyo'rnigaObject.hasOwnishlatish kerakligini ko'rsata olasiz. vazifalarga noma'lum filtr nomidan himoya qo'shasiz.
Oldin bilishingiz kerak: Obyektni himoyalash, Obyekt bo'ylab yurish, Obyekt: kalit-qiymat juftliklari, Tenglik va Object.is, Guruhlash: Object.groupBy.
1. Nega bu kerak?
Oxirgi uch darsda Object ning ko'p yangi metodlarini oldik: deskriptorlar, freeze, seal. 08-qismda esa keys, values, entries, hasOwn ni o'rgangan edik. Hammasi Object. bilan boshlanadi. Ular ko'paygan sari "qaysi biri nima qilardi?" degan savol tug'iladi.
Hayotdan o'xshatish: ustaning asboblar qutisi. Yangi usta asboblarni bitta qopga solib yuradi va har safar kerakligini topish uchun hammasini to'kib tashlaydi. Tajribali usta esa qutini bo'limlarga ajratgan: o'lchash, kesish, mahkamlash. Asbobning o'zini emas, qaysi bo'limda turishini eslaydi.
Bu dars — o'sha bo'limlarga ajratilgan quti. Avval to'liq xaritani ko'ramiz. Keyin hali o'rganilmagan yoki chala o'rganilgan metodlarni ochamiz: assign ning tuzoqlari, entries/fromEntries naqshi, getOwnPropertyNames, va nega hasOwnProperty eskirganini.
2. To'liq xarita
2.1 Olti bo'lim
Node 24 dagi Object ning barcha statik metodlari — 23 ta. Ularni vazifasi bo'yicha guruhlaymiz:
| Bo'lim | Metodlar | Qayerda |
|---|---|---|
| Ko'rish | keys, values, entries, getOwnPropertyNames, getOwnPropertySymbols |
Obyekt bo'ylab yurish, shu dars |
| Yasash va aylantirish | fromEntries, groupBy, create |
Guruhlash, Object.create |
| Nusxalash | assign |
shu dars |
| Tekshirish | hasOwn, is |
Tenglik, shu dars |
| Bo'lim | Metodlar | Qayerda |
|---|---|---|
| Himoya | freeze, isFrozen, seal, isSealed, preventExtensions, isExtensible |
Himoyalash |
| Deskriptor | defineProperty, defineProperties, getOwnPropertyDescriptor, getOwnPropertyDescriptors |
Deskriptorlar |
| Prototip | getPrototypeOf, setPrototypeOf |
Prototip |
Jadval telefonda sig'ishi uchun ikkiga bo'lingan. Prototip va create — Prototip va prototip zanjiri darsidan boshlab; hozir bilish shart emas. Qolgan hammasini bilasiz yoki bugun o'rganasiz.
Shu xaritani sxemada ko'ring — yodda saqlash uchun bo'lim nomlari yetarli:
flowchart LR
O(("Object.*")) --> K["Ko'rish"]
O --> Y["Yasash / aylantirish"]
O --> N["Nusxalash"]
O --> T["Tekshirish"]
O --> H["Himoya"]
O --> D["Deskriptor va prototip"]2.2 Nega obj.keys() emas, Object.keys(obj)?
Obyekt bo'ylab yurish darsida aytgan edik: bu metodlar sizning obyektingizda emas, Object ning o'zida turadi. Sababi bor. Agar keys har obyektning metodi bo'lsa, { keys: "kalitlar ro'yxati" } kabi obyektda u buzilardi — ma'lumot metod nomini egallab olardi. Object.keys(x) esa har qanday obyekt bilan, uning ichida nima bo'lishidan qat'i nazar, ishlaydi. Bu fikr «Tekshirish» bo'limida yana kerak bo'ladi.
2.3 Statik metodlar va har obyektdagi metodlar
Bitta chalkashlikni oldindan yechamiz. Object.keys — statik metod (static method): u Object ning o'zida turadi va obyektni argument sifatida oladi. Xuddi bozordagi umumiy tarozi kabi: u hech bir sotuvchiniki emas, har kim o'z mahsulotini olib kelib tortadi. Lekin har oddiy obyektda o'zi chaqira oladigan bir nechta metod ham bor: toString, valueOf, hasOwnProperty. Ular sizning obyektingizda yozilmagan — umumiy "ota" obyektdan meros keladi:
const taom = { nom: "Osh" };
console.log(taom.toString()); // [object Object]
console.log(Object.hasOwn(taom, "toString")); // false
console.log("toString" in taom); // true[object Object] — tanish satr: reduce darsida boshlang'ich qiymat unutilganda aynan shu chiqqan edi — obyekt satrga aylantirilganda toString ishlaydi. toString obyektning o'zida yo'q (hasOwn — false), lekin in uni ko'radi, chunki in merosni ham hisobga oladi. Bu farq darsning «Vazifalar qadami» da juda kerak bo'ladi. Meros qanday ishlashini — "ota" obyekt qayerda turishini — Prototip va prototip zanjiri darsida ochamiz.
Tekshirib ko'ring: Xaritadan toping: obyektni muzlatilganmi deb tekshiradigan metod qaysi bo'limda? Obyektni guruhlarga ajratadigan-chi?
Javob
Object.isFrozen — «Himoya» bo'limida (u tekshiradi, lekin himoya bilan bog'liq). Object.groupBy — «Yasash va aylantirish»: u massivdan yangi obyekt yasaydi. Bo'limlar — vazifa bo'yicha, metod nomidagi so'z bo'yicha emas.
3. Ko'rish: qaysi metod nimani ko'radi
3.1 getOwnPropertyNames
Object.keys faqat sanaladigan kalitlarni beradi (Xususiyat deskriptorlari). Object.getOwnPropertyNames esa — obyektning barcha o'z kalitlarini, sanalmaydiganlarini ham:
const narxlar = ["osh"];
console.log(Object.keys(narxlar)); // [ '0' ]
console.log(Object.getOwnPropertyNames(narxlar)); // [ '0', 'length' ]
console.log(Object.keys(Math).length); // 0
console.log(Object.getOwnPropertyNames(Math).length); // 44Math da Object.keys hech narsa topmadi — uning hamma xususiyati (PI, max, round...) sanalmaydigan. getOwnPropertyNames esa 44 tasini topdi. Bu metod ko'pincha "obyekt ichida nima bor?" deb o'rganish uchun kerak — masalan, yangi kutubxona obyektini konsolda tekshirganda.
Darsning boshidagi "23 ta metod" sonini aynan shu metod bilan sanadik. Object ning o'zi ham obyekt — uning ichiga qaraymiz:
const nomlar = Object.getOwnPropertyNames(Object);
const metodlar = nomlar.filter(
(nom) => typeof Object[nom] === "function",
);
console.log(metodlar.length); // 23
console.log(nomlar.filter((nom) => !metodlar.includes(nom)));Konsolda:
23
[ 'length', 'name', 'prototype' ]Object[nom] — kalit o'zgaruvchida bo'lgani uchun kvadrat qavs (Obyekt: kalit-qiymat juftliklari). Funksiya bo'lmagan uchta xususiyat — Object funksiya ekani bilan bog'liq texnik qismlar. Object.keys(Object) esa bo'sh massiv qaytarardi: bularning hammasi sanalmaydigan. Yangi muhitda (masalan, keyingi Node versiyasida) metod qo'shilsa, bu kod uni ham topadi — xaritani o'zingiz yangilay olasiz.
3.2 getOwnPropertySymbols
Kalit faqat satr emas, symbol ham bo'lishi mumkin — hech qachon boshqa kalit bilan to'qnashmaydigan maxsus qiymat. Uni Symbol darsida o'rganamiz, hozir bilish shart emas. Symbol kalitlarni na keys, na getOwnPropertyNames ko'rsatadi — ular uchun alohida Object.getOwnPropertySymbols bor.
3.3 Uch metod bir jadvalda
| Metod | Sanalmaydigan | Symbol | Meros |
|---|---|---|---|
Object.keys |
yo'q | yo'q | yo'q |
Object.getOwnPropertyNames |
ha | yo'q | yo'q |
Object.getOwnPropertySymbols |
ha | faqat symbol | yo'q |
Uchalasi ham faqat o'z kalitlarini beradi, meros kalitlar (toString kabi) hech birida yo'q. values va entries — keys bilan bir xil qoidada ishlaydi.
Tekshirib ko'ring:
Object.definePropertybilan yaratilgan, faqatvalueberilgan xususiyat uchta metoddan qaysi birida ko'rinadi?
Javob
Faqat Object.getOwnPropertyNames da. defineProperty da yozilmagan enumerable — false (Xususiyat deskriptorlari), shuning uchun Object.keys uni bermaydi. Kalit satr — symbol emas, demak getOwnPropertySymbols da ham yo'q.
4. entries → map → fromEntries
4.1 Naqsh
Obyektda map yo'q, filter yo'q. Massivda esa bor. Shuning uchun obyektni o'zgartirishning eng mashhur yo'li — uch qadamli "aylanma yo'l":
Object.entries(obj)— obyekt →[kalit, qiymat]juftliklari massivi.- Massiv metodlari —
map,filter,toSorted. Object.fromEntries(...)— juftliklar massivi → yangi obyekt.
Kechki aksiya: barcha narxlarga 10% chegirma.
const menyu = { osh: 35000, lagmon: 28000, manti: 30000, choy: 5000 };
const aksiya = Object.fromEntries(
Object.entries(menyu).map(([nom, narx]) => [nom, narx * 0.9]),
);
console.log(aksiya);
console.log(menyu.osh);Konsolda:
{ osh: 31500, lagmon: 25200, manti: 27000, choy: 4500 }
35000map callback'i massiv destructuring bilan juftlikni nom va narx ga ajratdi va yangi juftlik qaytardi. fromEntries ularni yig'di. Asl menyu o'zgarmadi — biz yangi obyekt yasadik. (Bu yerda natijalar butun chiqdi; kasrli natijada Pul va aniq hisob-kitob darsidagi Math.round kerak bo'ladi.)
Sxemada qadamlarni kuzating — obyekt massivga aylanadi, o'zgaradi va yana obyektga qaytadi:
flowchart LR
A["{ osh: 35000 }"] -- "Object.entries" --> B["[['osh', 35000]]"]
B -- "map / filter" --> C["[['osh', 31500]]"]
C -- "Object.fromEntries" --> D["{ osh: 31500 }"]4.2 Filtrlash va kalitlarni o'zgartirish
Xuddi shu naqsh filter bilan — 30 000 dan arzon taomlar:
const menyu = { osh: 35000, lagmon: 28000, manti: 30000, choy: 5000 };
const arzon = Object.fromEntries(
Object.entries(menyu).filter(([, narx]) => narx < 30000),
);
console.log(arzon); // { lagmon: 28000, choy: 5000 }[, narx] — birinchi elementni (nomni) o'tkazib yuborish: bizga faqat narx kerak.
Qiymatni emas, kalitni o'zgartirish ham mumkin. Masalan, ma'lumotni inglizcha nomli maydonlar kutadigan xizmatga yuborish kerak:
const mehmon = { ism: "Malika", telefon: "+998 90 000 00 00" };
const nomlar = { ism: "name", telefon: "phone" };
const tashqi = Object.fromEntries(
Object.entries(mehmon).map(([kalit, qiymat]) => [
nomlar[kalit],
qiymat,
]),
);
console.log(tashqi); // { name: 'Malika', phone: '+998 90 000 00 00' }Bu yerda nomlar — "lug'at": o'zbekcha kalit → inglizcha kalit.
4.3 Obyektni qiymat bo'yicha tartiblash
Obyektda sort ham yo'q. Lekin juftliklar massivini tartiblash mumkin — toSorted bilan. Menyuni arzondan qimmatga:
const menyu = { osh: 35000, lagmon: 28000, manti: 30000, choy: 5000 };
const juftlar = Object.entries(menyu).toSorted(
([, a], [, b]) => a - b,
);
const tartibli = Object.fromEntries(juftlar);
console.log(tartibli);
console.log(juftlar.at(-1));Konsolda:
{ choy: 5000, lagmon: 28000, manti: 30000, osh: 35000 }
[ 'osh', 35000 ]Taqqoslash funksiyasi juftlikni destructuring bilan ochadi va faqat narxlarni solishtiradi (sort va taqqoslash funksiyasi). fromEntries juftliklar tartibini saqlaydi — natijaviy obyektda kalitlar arzondan qimmatga turadi. juftlar.at(-1) — oxirgisi, ya'ni eng qimmat taom.
Bitta istisno bor. Obyekt bo'ylab yurish darsidagi qoida: butun songa o'xshash kalitlar ("1", "25") obyektda har doim o'sish tartibida turadi, qanday qo'shilganidan qat'i nazar. Shuning uchun kalitlari id raqamlari bo'lgan obyektni bu usul bilan tartiblab bo'lmaydi — tartib kerak bo'lsa, natijani massivligicha qoldiring.
Maslahat:
Object.fromEntriesfaqat massiv bilan emas, har qanday juftliklar ro'yxati bilan ishlaydi. Brauzerda eng foydali holat — forma:Object.fromEntries(new FormData(forma))butun formani bitta qatorda{ ism: "...", telefon: "..." }obyektiga aylantiradi (FormData).
Tekshirib ko'ring:
Object.fromEntries([["osh", 1], ["osh", 2]])nima qaytaradi?
Javob
{ osh: 2 }. Bitta kalit ikki marta kelsa, oxirgisi g'olib — xuddi obyektga ikki marta yozgandek: o.osh = 1; o.osh = 2;. Takroriy kalitlar haqida xato ham, ogohlantirish ham yo'q.
5. Object.assign
5.1 Nima qiladi
Sayoz va chuqur nusxalash darsida Object.assign ni spread'ning "eski akasi" sifatida ko'rgan edik. Imzosi:
Object.assign(nishon, manba1, manba2, ...);U har manbaning sanaladigan o'z xususiyatlarini nishonga yozadi va nishonning o'zini qaytaradi. Keyingi manba oldingisining bir xil kalitini bosib ketadi:
const asosiy = { til: "uz", chek: true };
const natija = Object.assign({}, asosiy, { chek: false });
console.log(natija); // { til: 'uz', chek: false }Birinchi argument — bo'sh {}. Shuning uchun natija yangi obyekt. Bu yozuv { ...a, ...b } bilan deyarli bir xil. Lekin "deyarli" so'zida ikki tuzoq yashiringan.
5.2 Tuzoq 1: birinchi argument o'zgaradi
const STANDART = { til: "uz", valyuta: "so'm", chek: true };
const sozlama = Object.assign(STANDART, { chek: false });
console.log(sozlama === STANDART); // true
console.log(STANDART.chek); // false{} unutildi — va assign standart sozlamalarning o'zini o'zgartirdi. Endi dasturning boshqa joylari ham chek: false ni ko'radi. Natija ham yangi obyekt emas — STANDART ning o'zi.
Qoida: assign dan nusxa uchun foydalansangiz, birinchi argument doim yangi {} bo'lsin. Yoki spread yozing — u bu xatoga yo'l qo'ymaydi: { ...STANDART, chek: false }. Agar STANDART muzlatilgan bo'lsa (Obyektni himoyalash), xatoli assign darhol TypeError berardi — freeze ning foydasi yana bir bor.
5.3 Tuzoq 2: setter'lar
assign nishonga oddiy tayinlash bilan yozadi: nishon.kalit = qiymat. Demak, nishonda setter bo'lsa — u chaqiriladi. Spread esa yangi obyektda xususiyatni to'g'ridan-to'g'ri yaratadi — setter'ga e'tibor bermaydi:
const mehmon = {
_telefon: "",
get telefon() {
return this._telefon;
},
set telefon(matn) {
this._telefon = matn.replaceAll(" ", "");
},
};
Object.assign(mehmon, { telefon: "+998 90 000 00 00" });
console.log(mehmon.telefon); // +998900000000
const nusxa = { ...mehmon, telefon: "+998 90 111 11 11" };
console.log(nusxa.telefon); // +998 90 111 11 11assign Getter va setter darsidagi tozalovchi setter'dan o'tdi — bo'sh joylar olib tashlandi. Spread esa nusxada telefon ni oddiy xususiyat qilib yaratdi: setter yo'q, tozalash yo'q. Ko'pincha bu farq sezilmaydi. Lekin setter'li obyektga ma'lumot "quyganda" — assign kerak.
Object.assign(nishon, ...) |
{ ...a, ...b } |
|
|---|---|---|
| Natija | nishonning o'zi | har doim yangi obyekt |
| Nishondagi setter | chaqiriladi | — |
| Manbadagi getter | chaqiriladi | chaqiriladi |
null/undefined manba |
o'tkazib yuboriladi | o'tkazib yuboriladi |
5.4 Manbadagi getter: qiymat ko'chadi
Xususiyat deskriptorlari darsida savol qoldirgan edik: Object.assign getter'ni qanday ko'chiradi? Javob — spread kabi: getter chaqiriladi, natijasi oddiy qiymat bo'lib yoziladi.
const savat = {
taomlar: [35000],
get jami() {
return this.taomlar.reduce((s, n) => s + n, 0);
},
};
const nusxa = Object.assign({}, savat);
nusxa.taomlar.push(5000);
console.log(nusxa.jami, savat.jami); // 35000 40000
const d = Object.getOwnPropertyDescriptor(nusxa, "jami");
console.log(d.value, d.get); // 35000 undefinedNusxada jami — value: 35000 li oddiy xususiyat, getter emas. taomlar esa umumiy massiv (sayoz nusxa), shuning uchun push ikkalasiga ham tegdi — lekin nusxadagi jami buni "bilmaydi". Getter'ni saqlab nusxalash — faqat deskriptorlar orqali: Object.defineProperties({}, Object.getOwnPropertyDescriptors(savat)).
Demak, assign ning ikki tomoni bor: nishonda u setter'larni ishga tushiradi, manbada esa getter'larni o'qiydi. Ikkalasida ham u xususiyatlarning "tavsifi" bilan emas, faqat qiymatlari bilan ishlaydi.
Tekshirib ko'ring:
const a = { x: 1 }; const b = Object.assign(a, { y: 2 });—a === bvaObject.keys(a)nima?
Javob
true va [ 'x', 'y' ]. assign a ni o'zgartirdi va o'shani qaytardi. b — yangi obyekt emas, a ga ikkinchi nom.
6. Tekshirish: hasOwn va is
6.1 hasOwnProperty ning ikki muammosi
Obyekt: kalit-qiymat juftliklari darsida Object.hasOwn ni o'rgangan va "eski kodda obj.hasOwnProperty("k") uchraydi" degan edik. Endi nega yangi kodda faqat Object.hasOwn yozilishini ko'ramiz.
Birinchi muammo: ba'zi obyektlarda hasOwnProperty umuman yo'q. Guruhlash darsidagi Object.groupBy natijasini eslang:
const guruh = Object.groupBy([35000, 5000, 28000], (n) =>
n > 20000 ? "qimmat" : "arzon",
);
console.log(guruh);
console.log(Object.hasOwn(guruh, "arzon")); // trueKonsolda:
[Object: null prototype] { qimmat: [ 35000, 28000 ], arzon: [ 5000 ] }
true[Object: null prototype] — bu obyekt hech kimdan "meros" olmagan. Oddiy obyektlar toString, hasOwnProperty kabi metodlarni umumiy "ota" obyektdan oladi (Prototip darsida batafsil). Bu obyektda esa ota yo'q — shuning uchun guruh.hasOwnProperty("arzon") TypeError: guruh.hasOwnProperty is not a function beradi. Object.hasOwn esa ishladi.
Ikkinchi muammo: ma'lumot metod nomini egallab olishi mumkin. Foydalanuvchi kiritgan kalitlardan obyekt yasaldi deylik:
const izohlar = { hasOwnProperty: "zo'r taom!", osh: "mazali" };
console.log(izohlar.hasOwnProperty("osh"));TypeError: izohlar.hasOwnProperty is not a functionTarjimasi: "izohlar.hasOwnProperty — funksiya emas". Obyektning o'zida hasOwnProperty degan satr paydo bo'ldi va u meros metodni to'sib qo'ydi. Bu — «Nega obj.keys() emas» bo'limidagi muammoning aynan o'zi. Hujumchi bunday kalitni ataylab yuborib, server kodini "sindirishi" mumkin. Object.hasOwn(izohlar, "osh") esa true qaytaradi — u Object da turadi va obyekt ichidagi narsaga bog'liq emas.
Qoida: har doim Object.hasOwn(obj, "kalit"). obj.hasOwnProperty(...) ni eski kodda ko'rsangiz — ma'nosi bir xil, lekin yangisida yozmang.
6.2 Object.is — eslatma
Tenglik va Object.is darsida Object.is ni === bilan solishtirgan edik. U ikki holatda farq qiladi:
console.log(NaN === NaN, Object.is(NaN, NaN)); // false true
console.log(0 === -0, Object.is(0, -0)); // true falseQolgan barcha holatlarda Object.is va === bir xil. Amalda Object.is ni kamdan-kam qo'lda yozasiz, lekin u ko'p kutubxonalar ichida ishlaydi. Masalan, React (interfeys yasash kutubxonasi — 17-qismda o'rganamiz, hozir bilish shart emas) holat o'zgarganini aynan Object.is bilan tekshiradi — yangi obyekt yasalmasa, havola o'sha-o'sha qoladi va ekran yangilanmaydi. Bu — keyingi darsning asosiy sababi.
Tekshirib ko'ring:
[NaN].includes(NaN)va[NaN].indexOf(NaN)nima qaytaradi? Qaysi biriObject.isga o'xshab ishlaydi?
Javob
true va -1. includes NaN'ni topadi — u Object.is ga yaqin qoida bilan solishtiradi (0 va -0 ni esa teng deb oladi). indexOf esa === ishlatadi, NaN === NaN — false, shuning uchun topolmaydi.
7. Ko'p uchraydigan xatolar
7.1 obj.keys() deb yozish
menyu.keys is not a function. Tuzatish: Object.keys(menyu) — metod Object da.
7.2 Object.assign(standart, ...) — standart buzildi
Birinchi argument o'zgaradi va qaytariladi. Tuzatish: Object.assign({}, standart, ...) yoki { ...standart, ... }.
7.3 fromEntries ga juftlik emas, qiymat qaytarish
Object.entries(m).map(([k, v]) => v * 0.9) — map sonlar massivi qaytaradi, fromEntries esa juftlik kutadi: TypeError: Iterator value 31500 is not an entry object. Tuzatish: [k, v * 0.9] — har doim ikki elementli massiv.
7.4 hasOwnProperty ni obyektning o'zidan chaqirish
Null-prototipli obyektda yoki ma'lumot nom egallaganda — TypeError. Tuzatish: Object.hasOwn.
7.5 Object.keys "hammasini" beradi deb o'ylash
Sanalmaydigan va symbol kalitlar unda yo'q. Tuzatish: obyektni o'rganayotganda — Object.getOwnPropertyNames yoki Object.getOwnPropertyDescriptors.
8. Mashqlar
1-mashq (oson): Narxlarni mingga yaxlitlash
Menyu narxlarini 15% oshiring va minggacha yaxlitlang. Asl menyu o'zgarmasin. Ishora: Math.round(x / 1000) * 1000 (Math obyekti); naqsh — entries → map → fromEntries.
const menyu = { osh: 35000, lagmon: 28000, manti: 30000, choy: 5000 };Yechim
const menyu = { osh: 35000, lagmon: 28000, manti: 30000, choy: 5000 };
const yangi = Object.fromEntries(
Object.entries(menyu).map(([nom, narx]) => [
nom,
Math.round((narx * 1.15) / 1000) * 1000,
]),
);
console.log(yangi);
console.log(menyu.osh);Konsolda:
{ osh: 40000, lagmon: 32000, manti: 35000, choy: 6000 }
3500035 000 × 1,15 = 40 250 → 40 000. Choy: 5 750 → 6 000. Naqsh uch qadam: juftliklar, har juftlikdan yangi juftlik, qaytarib obyekt.
2-mashq (o'rta): Sozlamalarni birlashtirish
sozlamaYasa(foydalanuvchi) funksiyasini yozing. U muzlatilgan STANDART ga foydalanuvchi sozlamalarini qo'shib, yangi obyekt qaytarsin. Foydalanuvchi undefined bersa ham ishlasin. STANDART hech qachon o'zgarmasin. Ishora: Object.assign undefined manbani o'tkazib yuboradi.
Yechim
const STANDART = Object.freeze({
til: "uz",
valyuta: "so'm",
chek: true,
});
function sozlamaYasa(foydalanuvchi) {
return Object.assign({}, STANDART, foydalanuvchi);
}
console.log(sozlamaYasa({ chek: false }));
console.log(sozlamaYasa(undefined));
console.log(STANDART.chek); // trueKonsolda:
{ til: 'uz', valyuta: "so'm", chek: false }
{ til: 'uz', valyuta: "so'm", chek: true }
trueBirinchi argument — yangi {}, shuning uchun STANDART ga tegilmaydi (u muzlagan — tegilsa, modulda xato chiqardi). undefined manba jimgina o'tkazib yuborildi. Spread varianti ham ishlaydi: { ...STANDART, ...foydalanuvchi } — ...undefined obyekt ichida xatosiz e'tiborsiz qoladi.
3-mashq (qiyin): Ikki obyekt farqi
farqlar(eski, yangi) funksiyasini yozing: { qoshildi, olibTashlandi, ozgardi } qaytarsin — har biri kalitlar massivi. Qiymatlarni Object.is bilan solishtiring. Ishora: Object.keys ikkala obyektdan, Object.hasOwn — kalit bormi, filter — tanlash.
Yechim
function farqlar(eski, yangi) {
const eskiKalitlar = Object.keys(eski);
const yangiKalitlar = Object.keys(yangi);
return {
qoshildi: yangiKalitlar.filter((k) => !Object.hasOwn(eski, k)),
olibTashlandi: eskiKalitlar.filter(
(k) => !Object.hasOwn(yangi, k),
),
ozgardi: eskiKalitlar.filter(
(k) => Object.hasOwn(yangi, k) && !Object.is(eski[k], yangi[k]),
),
};
}
const kecha = { osh: 35000, lagmon: 28000, somsa: 8000 };
const bugun = { osh: 38000, lagmon: 28000, manti: 30000 };
console.log(farqlar(kecha, bugun));Konsolda:
{
qoshildi: [ 'manti' ],
olibTashlandi: [ 'somsa' ],
ozgardi: [ 'osh' ]
}(38 000 — misol uchun, kanonik narx 35 000.) ozgardi da ikki shart: kalit yangi obyektda ham bor va qiymati boshqa. Birinchi shartsiz o'chirilgan somsa ham "o'zgardi" ro'yxatiga tushardi (8000 va undefined farqli). Object.is — NaN qiymatlarni ham to'g'ri solishtirishi uchun. Bu funksiya sayoz: ichma-ich obyektlarni havola bo'yicha solishtiradi.
4-mashq: Vazifalar qadami — noma'lum filtrdan himoya
refactor/obyektlar branch'ida davom etamiz. filtrniTanla(filtr) filtr nomini tugmaning data-filtr atributidan oladi va hech tekshirmaydi:
function filtrniTanla(filtr) {
holat.filtr = filtr;
holat.tahrirId = null;
render();
}HTML'da imlo xatosi bo'lsa (data-filtr="faoll") yoki kimdir DevTools'da atributni o'zgartirsa, holat.filtr ga noma'lum nom tushadi. mosmi uni "hammasi" deb tushunadi, boshMatnlar[holat.filtr] esa undefined beradi.
Funksiya boshiga tekshiruv qo'shing: filtr nomi boshMatnlar ning o'z kaliti bo'lmasa — console.warn bilan ogohlantirib, hech narsa qilmasin. Mavjud uch tugmada xulq o'zgarmasin.
Yechim
function filtrniTanla(filtr) {
if (!Object.hasOwn(boshMatnlar, filtr)) {
console.warn(`Noma'lum filtr: ${filtr}`);
return;
}
holat.filtr = filtr;
holat.tahrirId = null;
render();
}boshMatnlar — uchta to'g'ri filtr nomining yagona ro'yxati: hammasi, faol, bajarilgan. Yangi ro'yxat yaratmadik — mavjud muzlatilgan obyektning kalitlaridan foydalandik.
Nega in emas, Object.hasOwn? Node'da solishtiring:
const boshMatnlar = Object.freeze({
hammasi: "Hozircha vazifa yo'q. Birinchisini qo'shing!",
faol: "Faol vazifa yo'q.",
bajarilgan: "Bajarilgan vazifa hali yo'q.",
});
for (const nom of ["faol", "faoll", "toString"]) {
const meros = nom in boshMatnlar;
console.log(nom, meros, Object.hasOwn(boshMatnlar, nom));
}Konsolda:
faol true true
faoll false false
toString true false"toString" in boshMatnlar — true: in meros metodlarni ham ko'radi. Agar tekshiruv in bilan yozilsa, data-filtr="toString" li tugma tekshiruvdan o'tib ketardi. Brauzerda sinab ko'rdik: bunday tugma bosilganda holat.filtr "toString" bo'ladi, ro'yxat hamma vazifani ko'rsatadi, bo'sh ro'yxat xabari matniga esa function toString() { [native code] } yoziladi. Object.hasOwn bilan esa tugma hech narsa qilmaydi, konsolda faqat Noma'lum filtr: toString ogohlantirishi chiqadi.
Xulq o'zgarmaganini tekshiring: «Hammasi», «Faol», «Bajarilgan» — avvalgidek; "Bajarilgan" filtrida yangi vazifa qo'shilsa — filtr «Hammasi» ga o'tadi (bu yo'l ham filtrniTanla dan emas, vazifaQosh dan keladi, unga tegmadik).
Commit: Filtr: noma'lum filtr nomini Object.hasOwn bilan rad et.
9. Real ishda
- Ma'lumotni qayta shakllantirish. Serverdan kelgan javobni ilovaga kerakli ko'rinishga aylantirish —
entries/map/fromEntriesning kundalik ishi: kalitlarni qayta nomlash, keraksiz maydonlarni olib tashlash, qiymatlarni formatlash. - Sozlamalar. "Standart + foydalanuvchiniki" naqshi deyarli har kutubxonada bor:
Object.assign({}, standart, opsiyalar)yoki spread. Options obyekti darsidagi g'oyaning davomi. - Xavfsizlik. Foydalanuvchi yuborgan kalitni tekshirish — faqat
Object.hasOwn. Server kodidaobj.hasOwnPropertyni sindiradigan kalitlar — ma'lum hujum usuli; yana bir xavfli hujumni Prototype pollution darsida ko'ramiz. - Kod ko'rib chiqishda.
Object.assign(birorObyekt, ...)ni ko'rsangiz, birinchi savol: "bu obyektni o'zgartirish ataylabmi?". Ko'pincha javob "yo'q" bo'ladi va tuzatish bitta{}ga teng. Ikkinchi savol:for...in+hasOwnPropertyyozilgan eski siklniObject.entriesbilan qisqartirsa bo'lmaydimi? - React. Holat o'zgarishini
Object.isbilan tekshiradi — shuning uchun holat obyektlarini joyida o'zgartirmay, yangisini yasaymiz. - Intervyu. "
Object.assignva spread farqi?", "hasOwnnegahasOwnPropertydan yaxshi?", "obyektni qanday filtrlaysiz?" — o'rta darajali (middle) dasturchi intervyularida tez-tez uchraydi.
Xulosa
Objectning 23 statik metodi olti bo'limda: ko'rish, yasash/aylantirish, nusxalash, tekshirish, himoya, deskriptor/prototip.Object.keys— sanaladigan o'z kalitlar;getOwnPropertyNames— sanalmaydiganlari bilan;getOwnPropertySymbols— symbol kalitlar.- Obyektni o'zgartirish naqshi:
Object.fromEntries(Object.entries(o).map(...))— juftlik kiradi, juftlik chiqadi. Object.assignbirinchi argumentni o'zgartiradi va uni qaytaradi; nishondagi setter'larni chaqiradi. Nusxa uchun —{}yoki spread.- Har doim
Object.hasOwn:hasOwnPropertynull-prototipli obyektda yo'q va ma'lumot bilan to'silishi mumkin.
Keyingi dars: Ichma-ich ma'lumotni immutable yangilash — chuqur joylashgan qiymatni asl obyektga tegmasdan yangilaymiz va vazifalar ni muzlagan ma'lumot bilan ishlaydigan qilamiz.
Manbalar
- MDN: "Object" — "Static methods" bo'limi; "Object.assign()", "Object.fromEntries()", "Object.hasOwn()" — developer.mozilla.org
- ECMAScript 2025 Language Specification: "Properties of the Object Constructor" — tc39.es/ecma262
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!