Mundarija (37)
- Bu darsda
- 1. Nega bu kerak?
- 2. Eslatma: havola va nusxa
- 3. Sayoz nusxa (shallow copy)
- 3.1 Spread birinchi qavatni nusxalaydi
- 3.2 Tuzoq: ichma-ich obyekt
- 3.3 Xotira sxemasi
- 3.4 Massivda ham xuddi shunday
- 4. Sayoz nusxaning to'rt usuli
- 4.1 Obyekt uchun: spread va Object.assign
- 4.2 Massiv uchun: spread, slice va Array.from
- 5. Chuqur nusxa: structuredClone
- 5.1 Hamma qavatni nusxalash
- 5.2 U nimalarni nusxalay oladi
- 5.3 Nimani nusxalay olmaydi
- 6. Eski usul: JSON.parse(JSON.stringify(obj))
- 6.1 Qanday ishlaydi
- 6.2 Nimani yo'qotadi
- 6.3 Kutubxonalar haqida bir og'iz
- 7. Qaysi birini tanlash kerak?
- 8. Ichma-ich ma'lumotni immutable yangilash
- 8.1 Faqat o'zgaradigan yo'lni nusxalash
- 8.2 Massiv ichidagi obyektni yangilash
- 8.3 Bu nega muhim: React haqida bir gap
- 9. Ko'p uchraydigan xatolar
- 9.1 "Spread qildim — endi mustaqil"
- 9.2 Tayinlashni nusxa deb o'ylash
- 9.3 Metodli obyektni structuredClone qilish
- 9.4 JSON usulidan keyin "... is not a function"
- 9.5 Object.assign ga birinchi argument sifatida aslni berish
- 10. Mashqlar
- 1-mashq (oson): Natijani toping
- 2-mashq (o'rta): Qoralamani tuzating
- 3-mashq (qiyin): Immutable yangilash
- 11. Real ishda
- Xulosa
- 08-qism yakuni: endi nimalarni bilasiz
JavaScript'da obyektni nusxalash: sayoz va chuqur nusxa, structuredClone
Qisqacha: Spread (
{ ...obj }),Object.assignvaslice— sayoz nusxa: ular faqat birinchi qavatni nusxalaydi, ichma-ich obyektlar esa asl nusxa bilan umumiy bo'lib qoladi. To'liq mustaqil, chuqur nusxa uchunstructuredClone(obj)ishlatiladi. U funksiyalarni nusxalay olmaydi, eskiJSON.parse(JSON.stringify(obj))usuli esa sana,undefinedvaNaNni buzadi.
Bu darsda
- Sayoz nusxa nima ekanini va uning ichma-ich obyektdagi tuzog'ini tushuntira olasiz.
- Obyekt va massivni to'rt xil usulda sayoz nusxalay olasiz.
structuredClonebilan chuqur nusxa olasiz va u nimani nusxalay olmasligini bilasiz.- Eski JSON usuli nimalarni yo'qotishini tushunasiz.
- Ichma-ich ma'lumotni asl nusxaga tegmasdan yangilay olasiz.
Oldin bilishingiz kerak: Havola semantikasi, Spread va rest operatori, Parametrda destructuring va options obyekti.
1. Nega bu kerak?
Siz o'quv markazi saytida profil tahrirlash oynasini yasayapsiz. Foydalanuvchi "Tahrirlash" tugmasini bosadi. Siz profilning nusxasini olasiz — foydalanuvchi o'sha nusxani o'zgartiradi. "Bekor qilish" bosilsa, nusxa tashlab yuboriladi, asl profil esa joyida qoladi.
Siz spread bilan nusxa oldingiz:
const profil = { ism: "Malika", manzil: { shahar: "Toshkent" } };
const qoralama = { ...profil };
qoralama.manzil.shahar = "Samarqand";
console.log(profil.manzil.shahar); // SamarqandFoydalanuvchi hali hech narsani saqlamadi. Lekin asl profildagi shahar allaqachon o'zgarib ketdi! "Bekor qilish" endi hech narsani qaytarmaydi.
Bu — JavaScript'dagi eng ko'p uchraydigan yashirin xatolardan biri. Kod xato bermaydi, faqat ma'lumot "o'z-o'zidan" o'zgarib qoladi. Bu darsda buning sababini va to'g'ri yechimini ko'ramiz.
2. Eslatma: havola va nusxa
Havola semantikasi darsidan asosiy qoidani eslang. Obyekt o'zgaruvchining ichida emas, xotirada alohida turadi. O'zgaruvchida faqat unga havola — "manzil" saqlanadi.
const a = { ism: "Ali" };
const b = a;
b.ism = "Vali";
console.log(a.ism); // Vali
console.log(a === b); // trueconst b = a — bu umuman nusxa emas. Ikki o'zgaruvchi bitta obyektga qarab turibdi. === obyektlarda qiymatni emas, havolani solishtiradi: true — "bu bitta obyekt" degani.
Nusxa olish — xotirada yangi obyekt yaratish demak. Savol esa shunda: yangi obyekt ichiga nima tushadi?
3. Sayoz nusxa (shallow copy)
3.1 Spread birinchi qavatni nusxalaydi
const asl = { ism: "Malika", yosh: 20 };
const nusxa = { ...asl };
nusxa.ism = "Dilnoza";
console.log(asl.ism); // Malika
console.log(nusxa.ism); // Dilnoza
console.log(asl === nusxa); // falseBu yerda hammasi to'g'ri ishladi. { ...asl } yangi obyekt yaratdi (asl === nusxa — false). Nusxadagi ism ni o'zgartirish aslga ta'sir qilmadi.
Sayoz nusxa (shallow copy) — obyektning faqat birinchi qavatini nusxalash. Yangi obyekt yaratiladi va asl obyektdagi har bir xususiyat unga ko'chiriladi. Lekin xususiyatning qiymati obyekt bo'lsa, o'sha ichki obyekt nusxalanmaydi — faqat unga havola ko'chadi.
Hayotdan o'xshatish: omborxona ro'yxatini kseroksda ko'chirish. Varaqda "Stol — 3 ta" deb yozilgan qatorlar ham bor, "Asboblar — 7-shkafda" degan qator ham bor. Ksero nusxada ham xuddi shu yoziladi: "7-shkafda". Lekin shkafning o'zi ikkita bo'lib qolmaydi! Bitta varaq egasi shkafdan bolg'ani olsa, ikkinchi varaq egasi ham shkafni bo'sh ko'radi.
3.2 Tuzoq: ichma-ich obyekt
Endi birinchi bo'limdagi misolga qaytamiz va nima bo'lganini tekshiramiz:
const profil = { ism: "Malika", manzil: { shahar: "Toshkent" } };
const qoralama = { ...profil };
console.log(profil === qoralama); // false
console.log(profil.manzil === qoralama.manzil); // trueTashqi obyektlar har xil (false). Lekin manzil ikkalasida ham bitta obyekt (true)! Spread manzil xususiyatini ko'chirdi — ya'ni ichki obyektga havolani ko'chirdi. Ichki obyektning o'zi esa nusxalanmadi.
3.3 Xotira sxemasi
Xotirani raqamlangan qutilar deb tasavvur qilaylik. { ...profil } dan keyin xotira shunday ko'rinadi:
| Quti | Ichida | Kim qaraydi |
|---|---|---|
| #1 | ism: "Malika", manzil: → #3 |
profil |
| #2 | ism: "Malika", manzil: → #3 |
qoralama |
| #3 | shahar: "Toshkent" |
#1 va #2 ikkalasi |
Jadvalni o'qing: #1 va #2 — ikki alohida obyekt. Lekin ikkalasining manzil xususiyati bitta qutiga — #3 ga ishora qiladi.
Shuning uchun:
qoralama.ism = "Dilnoza"— faqat #2 qutini o'zgartiradi. Asl profil xavfsiz.qoralama.manzil.shahar = "Samarqand"— avval #3 qutiga boradi, keyin uni o'zgartiradi. #3 esaprofilniki ham. Shuning uchun asl profil ham o'zgaradi.
Maslahat: Qoida: son, satr, boolean kabi primitiv qiymatlar nusxada har doim mustaqil. Obyekt va massiv qiymatlar esa sayoz nusxada umumiy bo'lib qoladi.
3.4 Massivda ham xuddi shunday
Massiv ichida obyektlar bo'lsa, xuddi shu tuzoq takrorlanadi:
const savat = [
{ nomi: "Non", soni: 2 },
{ nomi: "Sut", soni: 1 },
];
const nusxa = [...savat];
nusxa[0].soni = 10;
console.log(savat[0].soni); // 10
console.log(savat === nusxa); // false
console.log(savat[0] === nusxa[0]); // trueMassivning o'zi yangi. Lekin uning ichidagi obyektlar — o'sha eskilari. Nusxa massivga yangi element qo'shsangiz (push), asl massiv o'zgarmaydi. Mavjud elementning ichini o'zgartirsangiz — ikkalasida ham o'zgaradi.
Tekshirib ko'ring: Konsolda nima chiqadi?
jsconst kurs = { nomi: "JS", teglar: ["web", "frontend"] }; const nusxa = { ...kurs }; nusxa.nomi = "Python"; nusxa.teglar.push("backend"); console.log(kurs.nomi); console.log(kurs.teglar.length);
Javob
JS va 3. nomi — satr, birinchi qavatda turadi, shuning uchun nusxada mustaqil. teglar esa massiv: sayoz nusxada ikkala obyekt bitta massivga qaraydi. Nusxa orqali push qilingan "backend" asl kursda ham paydo bo'ldi.
4. Sayoz nusxaning to'rt usuli
Spread yagona usul emas. Real kodda to'rttasini ham uchratasiz. Hammasi bir xil darajada — sayoz nusxa oladi.
4.1 Obyekt uchun: spread va Object.assign
Object.assign(nishon, manba) — manba obyektdagi hamma xususiyatni nishon obyektga ko'chiradi va nishonni qaytaradi. Nishon sifatida bo'sh {} bersangiz — natija yangi nusxa bo'ladi:
const narxlar = { choy: 5000, non: 4000 };
const nusxa1 = { ...narxlar };
const nusxa2 = Object.assign({}, narxlar);
console.log(nusxa2); // { choy: 5000, non: 4000 }
console.log(nusxa2 === narxlar); // falseObject.assign spread paydo bo'lishidan (2018) oldingi usul. Eski kodda va ba'zi kutubxonalarda ko'p uchraydi. Yangi kodda spread qisqaroq va o'qilishi osonroq.
4.2 Massiv uchun: spread, slice va Array.from
const mevalar = ["olma", "anor", "uzum"];
const n1 = [...mevalar];
const n2 = mevalar.slice();
const n3 = Array.from(mevalar);
console.log(n3); // [ 'olma', 'anor', 'uzum' ]
console.log(n1 === mevalar, n2 === mevalar); // false falseslice()argumentsiz chaqirilsa, massivni boshidan oxirigacha kesadi — ya'ni to'liq nusxa beradi.Array.from(x)—xdan yangi massiv yasaydi. U massivga o'xshagan boshqa narsalardan ham massiv yasay oladi (masalan, satrdan:Array.from("salom")). Bu imkoniyat keyingi qismlarda kerak bo'ladi.
| Usul | Nima uchun | Nusxa turi |
|---|---|---|
{ ...obj } |
Obyekt | Sayoz |
Object.assign({}, obj) |
Obyekt | Sayoz |
[...arr], arr.slice() |
Massiv | Sayoz |
Array.from(arr) |
Massiv | Sayoz |
Jadvaldagi oxirgi ustunga e'tibor bering: to'rttasi ham sayoz. Ichma-ich obyekt bo'lsa, ularning birortasi ham sizni tuzoqdan qutqarmaydi.
Diqqat:
Object.assignbirinchi argumentni o'zgartiradi.Object.assign(profil, { yosh: 21 })deb yozsangiz, nusxa olinmaydi — aslprofilning o'zi o'zgaradi. Nusxa kerak bo'lsa, birinchi argument har doim bo'sh{}bo'lsin.
5. Chuqur nusxa: structuredClone
5.1 Hamma qavatni nusxalash
Chuqur nusxa (deep copy) — obyektni ichidagi barcha ichma-ich obyektlari bilan birga, har qavatda yangidan nusxalash. Natija asl nusxa bilan hech qanday umumiy qismga ega bo'lmaydi.
Ombor o'xshatishida: ro'yxatni ko'chiribgina qolmay, yangi shkaf olib, ichiga asboblarning ham nusxasini qo'yish.
Zamonaviy JavaScript'da buning uchun tayyor funksiya bor — structuredClone:
const profil = { ism: "Malika", manzil: { shahar: "Toshkent" } };
const qoralama = structuredClone(profil);
qoralama.manzil.shahar = "Samarqand";
console.log(profil.manzil.shahar); // Toshkent
console.log(profil.manzil === qoralama.manzil); // falseMuammo hal bo'ldi. Endi manzil ham alohida nusxalandi: asl profil daxlsiz.
structuredClone 2022-yildan beri barcha zamonaviy brauzerlarda va Node 17+ da bor. Hech narsa o'rnatish yoki import qilish kerak emas.
5.2 U nimalarni nusxalay oladi
structuredClone faqat oddiy obyekt va massivlarni emas, ko'p boshqa turlarni ham to'g'ri nusxalaydi:
const buyurtma = {
id: 7,
sana: new Date("2026-09-27"),
izoh: undefined,
chegirma: NaN,
taomlar: [{ nomi: "Osh", soni: 2 }],
};
const nusxa = structuredClone(buyurtma);
console.log(nusxa.sana.getFullYear()); // 2026
console.log("izoh" in nusxa); // true
console.log(nusxa.chegirma); // NaN
console.log(nusxa.taomlar[0] === buyurtma.taomlar[0]); // falsenew Date("2026-09-27") — sana saqlaydigan obyekt, getFullYear() esa undan yilni oladi. Sanalarni alohida darsda o'rganamiz, hozir faqat "bu sana" deb biling. Muhimi: nusxada ham u haqiqiy sana bo'lib qoldi. undefined qiymatli xususiyat va NaN ham joyida.
structuredClone yana Map, Set (keyinroq o'rganadigan ma'lumot tuzilmalari) va hatto o'z-o'ziga havola qilgan obyektlarni ham to'g'ri nusxalaydi.
5.3 Nimani nusxalay olmaydi
Funksiyani nusxalay olmaydi. Obyektda funksiya (yoki metod) bo'lsa, xato beradi:
const talaba = { ism: "Jasur", salomBer: () => "Salom!" };
const nusxa = structuredClone(talaba);Node'da:
DOMException [DataCloneError]: () => "Salom!" could not be cloned.Tarjimasi: "Nusxalash xatosi: () => "Salom!" nusxalanmaydi". JavaScript xabarga funksiyaning kodini qo'yib, aynan qaysi qiymat to'sqinlik qilganini ko'rsatadi. Funksiya uzun bo'lsa, xabar ham bir necha qatorga cho'ziladi. DataCloneError — "ma'lumotni klonlash xatosi". DOMException — brauzer standartidan kelgan xato turi, uni hozir chuqur bilish shart emas. Brauzer konsolida xabar biroz boshqacha: DataCloneError: Failed to execute 'structuredClone' on 'Window': ... could not be cloned. Ma'nosi bir xil.
Nega aynan funksiya? structuredClone faqat ma'lumotni nusxalaydi. Funksiya esa ma'lumot emas, bajariladigan kod. Uni boshqa joyga to'g'ri ko'chirishning umumiy usuli yo'q.
Yana ikki narsa nusxalanmaydi:
- DOM elementlari — sahifadagi HTML elementlarning JavaScript'dagi ko'rinishi. Ularni keyingi qismda o'rganamiz.
structuredClonega tugma yoki<div>bersangiz, xuddi shuDataCloneErrorchiqadi. - Klass nusxalari xato bermaydi, lekin nusxa oddiy obyektga aylanadi — metodlari yo'qoladi. Klasslarni kursning keyingi qismida o'rganamiz, hozir bilish shart emas.
Maslahat: Amaliy qoida: ma'lumotni (son, satr, massiv, oddiy obyekt) funksiyalardan alohida saqlang. Shunda uni har doim bemalol nusxalay olasiz. React va boshqa vositalardagi "holat" (state) aynan shunday toza ma'lumot bo'ladi.
Tekshirib ko'ring: Qaysi obyektni
structuredClonexatosiz nusxalaydi?A)
{ ism: "Ali", baholar: [5, 4, 5] }B){ ism: "Ali", hisobla: () => 5 }C){ ism: "Ali", tugilgan: new Date("2005-03-21") }
Javob
A va C. A — oddiy satr va massiv. C — sana, structuredClone uni to'g'ri nusxalaydi. B da esa funksiya bor (arrow ham funksiya), shuning uchun DataCloneError chiqadi.
6. Eski usul: JSON.parse(JSON.stringify(obj))
6.1 Qanday ishlaydi
structuredClone paydo bo'lishidan oldin dasturchilar boshqa hiyla ishlatardi. Uni eski kodda va internetdagi eski javoblarda ko'p uchratasiz:
const asl = { ism: "Malika", manzil: { shahar: "Toshkent" } };
const nusxa = JSON.parse(JSON.stringify(asl));
nusxa.manzil.shahar = "Samarqand";
console.log(asl.manzil.shahar); // ToshkentJSON formatini birinchi qismlarda ko'rgansiz — u ma'lumotni matn ko'rinishida saqlaydi. JSON.stringify(obj) obyektni JSON matniga aylantiradi. JSON.parse(matn) esa matndan butunlay yangi obyekt yasaydi. Ikkalasini JSON darsida batafsil o'rganamiz.
Ya'ni obyekt avval matnga "eritiladi", keyin matndan qaytadan "quyiladi". Natijada eski obyekt bilan hech qanday havola qolmaydi.
6.2 Nimani yo'qotadi
Muammo shundaki, JSON faqat oddiy turlarni biladi. Qolganlari yo'l-yo'lakay buziladi:
const buyurtma = {
sana: new Date("2026-09-27"),
izoh: undefined,
chegirma: NaN,
hisobla() {
return 0;
},
};
const nusxa = JSON.parse(JSON.stringify(buyurtma));
console.log(nusxa);
console.log(typeof nusxa.sana);Konsolda:
{ sana: '2026-09-27T00:00:00.000Z', chegirma: null }
stringXato chiqmadi — va aynan shu xavfli. Natijani solishtiramiz:
| Asl qiymat | JSON nusxada | structuredClone da |
|---|---|---|
Sana (Date) |
Satr bo'lib qoldi | Sana |
undefined |
Xususiyat yo'qoldi | undefined |
| Funksiya | Xususiyat yo'qoldi | DataCloneError |
NaN, Infinity |
null |
O'zi |
Sana satrga aylangani keyinroq kutilmagan xato beradi. Masalan, nusxa.sana.getFullYear() chaqirsangiz:
TypeError: nusxa.sana.getFullYear is not a function"nusxa.sana.getFullYear — funksiya emas". Chunki nusxa.sana endi oddiy satr, satrda esa bunday metod yo'q. Xato nusxa olingan joyda emas, ancha keyin chiqadi — sababini topish qiyin.
Yana bir farq: JSON usuli o'z-o'ziga havola qilgan obyektda TypeError: Converting circular structure to JSON beradi. structuredClone bunday obyektni ham bemalol nusxalaydi.
Maslahat: Yangi kodda chuqur nusxa uchun
structuredCloneishlating. JSON usulini faqat ma'lumot aniq oddiy bo'lsa (son, satr, boolean, massiv, obyekt) va eski muhitda ishlash kerak bo'lsa qo'llang.
6.3 Kutubxonalar haqida bir og'iz
Eski loyihalarda _.cloneDeep(obj) ni ham ko'rasiz. Bu — lodash kutubxonasining chuqur nusxa funksiyasi (lodash — npm'dagi mashhur yordamchi funksiyalar to'plami). Bugun ko'p holatda uning o'rniga o'rnatilgan structuredClone yetarli.
7. Qaysi birini tanlash kerak?
| Vaziyat | Tanlov |
|---|---|
| Faqat birinchi qavat bor | Spread { ...obj } / [...arr] |
| Ichma-ich, to'liq mustaqil nusxa kerak | structuredClone |
| Ichida funksiya bor | Ma'lumotni funksiyadan ajrating |
| Bitta ichki qiymatni yangilash | Immutable yangilash (pastda) |
Chuqur nusxani "har ehtimolga qarshi" hamma joyda ishlatmang. Katta obyektni har safar to'liq nusxalash sekin va xotirani ko'p egallaydi. Ko'pincha kerak bo'lgani — keyingi bo'limdagi usul.
8. Ichma-ich ma'lumotni immutable yangilash
8.1 Faqat o'zgaradigan yo'lni nusxalash
Profil ichida faqat shaharni o'zgartirish kerak. Butun profilni chuqur nusxalash shart emas. O'zgaradigan "yo'l"dagi har bir qavatni spread bilan nusxalash yetarli:
const profil = {
ism: "Malika",
manzil: { shahar: "Toshkent", tuman: "Chilonzor" },
kurslar: ["JS", "Python"],
};
const yangi = {
...profil,
manzil: { ...profil.manzil, shahar: "Samarqand" },
};
console.log(profil.manzil.shahar);
console.log(yangi.manzil);
console.log(yangi.kurslar === profil.kurslar);Konsolda:
Toshkent
{ shahar: 'Samarqand', tuman: 'Chilonzor' }
trueQatorma-qator:
...profil— tashqi qavat nusxalandi: yangi obyekt.manzil: { ...profil.manzil, shahar: "Samarqand" }—manzilham yangi obyekt. Undagi eski xususiyatlar ko'chirildi, keyinshaharustidan yozildi.kurslarga tegmadik — u ikkala obyektda umumiy qoldi (true).
Oxirgi qator xato emas, balki afzallik. kurslar o'zgarmadi, demak uni nusxalashga hojat yo'q. O'zgargan qismi yangi, o'zgarmagani eskisi bilan umumiy.
Immutable yangilash (immutable — "o'zgarmas") — asl ma'lumotga tegmasdan, o'zgarishlar kiritilgan yangi nusxa yasash. Asl ma'lumotni joyida o'zgartirish esa mutatsiya deyiladi.
8.2 Massiv ichidagi obyektni yangilash
Savatdagi ikkinchi mahsulot sonini 3 ga o'zgartiramiz:
const savat = [
{ nomi: "Non", soni: 2 },
{ nomi: "Sut", soni: 1 },
];
const yangiSavat = [...savat];
yangiSavat[1] = { ...savat[1], soni: 3 };
console.log(savat[1].soni); // 1
console.log(yangiSavat[1].soni); // 3
console.log(yangiSavat[0] === savat[0]); // trueAvval massivning sayoz nusxasi olindi. Keyin o'zgaradigan element o'rniga yangi obyekt qo'yildi. Birinchi mahsulot umumiy qoldi — u o'zgarmagan.
Massivlarni bunday yangilashning qisqaroq usullari (map, with) bor. Ularni map darsida va nusxa bilan o'zgartirish darsida ko'ramiz.
8.3 Bu nega muhim: React haqida bir gap
React — sayt interfeysini yasaydigan eng mashhur kutubxona, unga kursda alohida qism bor. U ma'lumot o'zgarganini === bilan tekshiradi. Obyekt joyida o'zgartirilsa, havola o'sha-o'sha qoladi — React o'zgarishni sezmaydi va ekran yangilanmaydi. Yangi obyekt yasalsa, havola o'zgaradi va ekran yangilanadi.
Shu sababli React bilan ishlaganda siz har kuni aynan profil misolidagi naqshni yozasiz. To'liq amaliyot — ichma-ich ma'lumotni immutable yangilash darsida.
Tekshirib ko'ring: Bo'sh joyni to'ldiring.
const s = { til: "uz", ovoz: { baland: 5 } }obyektida faqatbalandni 8 ga o'zgartiramiz:const y = { ...s, ovoz: { , baland: 8 } };. Shundan keyins.ovoz.balandning qiymati bo'ladi.
9. Ko'p uchraydigan xatolar
9.1 "Spread qildim — endi mustaqil"
Eng ko'p uchraydigan xato. Spread faqat birinchi qavatni nusxalaydi. Obyekt ichida obyekt yoki massiv bo'lsa, ular umumiy qoladi. Tekshirish usuli: asl.ichki === nusxa.ichki — true chiqsa, ichki qism umumiy.
9.2 Tayinlashni nusxa deb o'ylash
const asl = { ism: "Ali" };
const nusxa = asl;
nusxa.ism = "Vali";
console.log(asl.ism); // Vali= hech narsani nusxalamaydi, faqat havolani ko'chiradi. Nusxa uchun kamida { ...asl } kerak.
9.3 Metodli obyektni structuredClone qilish
DOMException [DataCloneError]: () => "Salom!" could not be cloned.Obyektda funksiya bor. Yechim: nusxalashdan oldin faqat ma'lumot qismini ajrating yoki spread ishlating (u funksiyani havola sifatida ko'chiradi).
9.4 JSON usulidan keyin "... is not a function"
TypeError: nusxa.sana.getFullYear is not a functionJSON nusxada sana satrga aylangan. structuredClone ga o'ting.
9.5 Object.assign ga birinchi argument sifatida aslni berish
const asl = { ism: "Ali", yosh: 20 };
const nusxa = Object.assign(asl, { yosh: 21 });
console.log(asl.yosh); // 21
console.log(nusxa === asl); // trueObject.assign birinchi argumentni o'zgartiradi va uning o'zini qaytaradi. To'g'risi: Object.assign({}, asl, { yosh: 21 }) yoki { ...asl, yosh: 21 }.
10. Mashqlar
1-mashq (oson): Natijani toping
Kodni ishga tushirmasdan, konsolda nima chiqishini ayting. Keyin tekshiring.
const kitob = { nomi: "Alpomish", muallif: { ism: "Xalq" } };
const nusxa = { ...kitob };
nusxa.nomi = "Kuntug'mish";
nusxa.muallif.ism = "Fozil Yo'ldosh o'g'li";
console.log(kitob.nomi);
console.log(kitob.muallif.ism);Yechim
const kitob = { nomi: "Alpomish", muallif: { ism: "Xalq" } };
const nusxa = { ...kitob };
nusxa.nomi = "Kuntug'mish";
nusxa.muallif.ism = "Fozil Yo'ldosh o'g'li";
console.log(kitob.nomi); // Alpomish
console.log(kitob.muallif.ism); // Fozil Yo'ldosh o'g'linomi — birinchi qavatdagi satr, nusxada mustaqil. muallif esa ichma-ich obyekt: sayoz nusxada ikkalasi bitta obyektga qaraydi.
2-mashq (o'rta): Qoralamani tuzating
Quyidagi kodda qoralama ni o'zgartirish asl sozlama ni ham buzyapti. Bitta qatorni o'zgartirib, xatoni tuzating: sozlama.bildirishnoma.email true bo'lib qolsin. structuredClone ni ishlating.
const sozlama = {
til: "uz",
bildirishnoma: { email: true, sms: false },
};
const qoralama = { ...sozlama };
qoralama.bildirishnoma.email = false;
console.log(sozlama.bildirishnoma.email); // falseYechim
const sozlama = {
til: "uz",
bildirishnoma: { email: true, sms: false },
};
const qoralama = structuredClone(sozlama);
qoralama.bildirishnoma.email = false;
console.log(sozlama.bildirishnoma.email); // true
console.log(qoralama.bildirishnoma.email); // falsestructuredClone bildirishnoma ni ham alohida nusxaladi. Endi qoralama ni istalgancha o'zgartirsangiz ham, asl sozlama daxlsiz.
3-mashq (qiyin): Immutable yangilash
baholarniYangila(talaba, fan, baho) funksiyasini yozing. U talaba obyektini o'zgartirmasdan, baholar ichidagi fan ga baho qo'yilgan yangi obyekt qaytarsin. structuredClone ishlatmang — faqat spread. Kalitni o'zgaruvchidan olish uchun computed kalit [fan]: baho kerak bo'ladi.
const talaba = {
ism: "Nodira",
baholar: { matematika: 4, fizika: 5 },
guruh: { nomi: "JS-12" },
};Tekshiring: asl talaba.baholar.matematika 4 bo'lib qolsin, guruh esa yangi obyektda eski obyekt bilan umumiy bo'lsin.
Yechim
function baholarniYangila(talaba, fan, baho) {
return {
...talaba,
baholar: { ...talaba.baholar, [fan]: baho },
};
}
const talaba = {
ism: "Nodira",
baholar: { matematika: 4, fizika: 5 },
guruh: { nomi: "JS-12" },
};
const yangi = baholarniYangila(talaba, "matematika", 5);
console.log(talaba.baholar.matematika); // 4
console.log(yangi.baholar); // { matematika: 5, fizika: 5 }
console.log(yangi.guruh === talaba.guruh); // trueFaqat o'zgaradigan yo'l nusxalandi: tashqi obyekt va baholar. guruh ga tegmadik, shuning uchun u umumiy qoldi. Funksiya toza funksiya: kirgan obyektni o'zgartirmaydi, yangi natija qaytaradi.
11. Real ishda
- React va Redux: holatni (state) yangilashda har doim shu darsdagi immutable naqsh ishlatiladi. Joyida o'zgartirish — React'da ekran yangilanmasligining eng ko'p sababi.
- Formalar va "Bekor qilish": tahrirlashdan oldin
structuredClonebilan qoralama olinadi. - Undo (ortga qaytarish): har bir o'zgarishdan oldingi holat saqlanadi. Sayoz nusxada bu tarix "o'z-o'zidan" buzilib ketadi.
- Web Worker va
postMessage: brauzer ma'lumotni boshqa oqimga yuborganda aynanstructuredClonealgoritmini ishlatadi. Funksiya yuborib bo'lmasligi ham shundan.
Intervyuda "Shallow va deep copy farqi nima?" savoli deyarli har doim beriladi. Yaxshi javob: sayoz nusxa faqat birinchi qavatni ko'chiradi, ichki obyektlar havola bilan umumiy qoladi; chuqur nusxa hamma qavatni ko'chiradi — zamonaviy usul structuredClone, JSON usuli esa sana va undefined ni yo'qotadi.
Xulosa
const b = a— nusxa emas, bitta obyektga ikkinchi havola.- Spread,
Object.assign({}, obj),slice(),Array.from— sayoz nusxa: ichki obyektlar umumiy qoladi. structuredClone(obj)— chuqur nusxa: sana,Map,Setham to'g'ri; funksiya va DOM elementidaDataCloneError.JSON.parse(JSON.stringify(obj))— eski usul: sana satrga aylanadi,undefinedva funksiya yo'qoladi,NaN→null.- Ichma-ich yangilashda faqat o'zgaradigan yo'lni spread bilan nusxalang — bu React'ning kundalik naqshi.
08-qism yakuni: endi nimalarni bilasiz
Tabriklaymiz — "JavaScript asoslari" qismi tugadi! 61 dars oldin siz JavaScript'da bitta qator ham yozmagan edingiz. Endi esa:
- O'zgaruvchi, ma'lumot turlari va operatorlar bilan ishlaysiz.
==va===farqini, yashirin tur o'zgarishlarini tushunasiz. - Matn va sonlar bilan ishlaysiz: qidirish, kesish, formatlash, aniq pul hisobi.
if,switchva sikllar bilan dastur mantiqini qurasiz.- Funksiya yozasiz: parametr,
return, arrow, callback, scope, rekursiya. - Massiv va obyektlarni yaratasiz, aylanasiz, destructuring va spread qilasiz, to'g'ri nusxalaysiz.
- Xatoni o'qiysiz va DevTools bilan kodni qadamma-qadam tekshirasiz.
Bu — har qanday JavaScript dasturining "tili". Lekin hozircha kodingiz faqat konsolda yashaydi.
Keyingi qism — "JavaScript brauzerda va debugging". Unda JavaScript'ni sahifaga ulaymiz: tugma bosilganda nimadir sodir bo'ladi, forma to'ldiriladi, ro'yxat ekranda chiziladi. Shu qismda birinchi haqiqiy interaktiv ilovangizni — vazifalar ro'yxatini yasaysiz. Bu qismda o'rgangan obyekt, massiv va immutable yangilash u yerda har qadamda kerak bo'ladi.
Keyingi dars: Brauzer muhiti: window, document va skript yuklanishi — brauzer JavaScript'ga qanday imkoniyatlar berishini va skript sahifaga qachon yuklanishini o'rganamiz.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!