Ob'ekt metodlari — Object.keys, values, entries, assign, freeze

~15 daq · JavaScript · Ob'ektlar va Massivlar

Muammodan boshlaylik

Sizda foydalanuvchi ma'lumotlari bor. Barcha kalitlarni ro'yxat qilib chiqarish kerak. Yoki ikki ob'ektni birlashtirish kerak. Yoki ob'ekt o'zgartirilmasligi uchun "qulflash" kerak.

Bularning har biri uchun alohida kod yozish shart emas — JavaScript ning Object da tayyor metodlar bor. Bu darsda ularni o'rganamiz.


Object.keys — kalitlar ro'yxati

Object.keys() ob'ektning barcha kalitlarini massiv ko'rinishida qaytaradi.

const foydalanuvchi = {
  ism: "Jasur",
  yosh: 24,
  shahar: "Toshkent"
};

console.log(Object.keys(foydalanuvchi));
// ["ism", "yosh", "shahar"]

Bu massiv bo'lgani uchun unga massiv metodlarini qo'llash mumkin:

const kalitlar = Object.keys(foydalanuvchi);

kalitlar.forEach((kalit) => {
  console.log(kalit); // "ism", "yosh", "shahar"
});

console.log(kalitlar.length); //  3 — ob'ektda nechta xususiyat bor

Object.values — qiymatlar ro'yxati

Object.values() ob'ektning barcha qiymatlarini massiv ko'rinishida qaytaradi.

const mahsulot = {
  nomi: "Noutbuk",
  narxi: 8000000,
  soni: 5
};

console.log(Object.values(mahsulot));
// ["Noutbuk", 8000000, 5]

Amaliy misol — barcha narxlar yig'indisi:

const narxlar = {
  noutbuk: 8000000,
  sichqoncha: 150000,
  klaviatura: 300000
};

const jami = Object.values(narxlar).reduce((yig, narx) => yig + narx, 0);
console.log(jami); // 8450000

Object.entries — kalit-qiymat juftliklari

Object.entries() ob'ektning har bir xususiyatini [kalit, qiymat] ko'rinishidagi massiv sifatida qaytaradi. Natija — massivlar massivi.

const foydalanuvchi = {
  ism: "Jasur",
  yosh: 24,
  shahar: "Toshkent"
};

console.log(Object.entries(foydalanuvchi));
// [["ism", "Jasur"], ["yosh", 24], ["shahar", "Toshkent"]]

for...of bilan birga ishlatilganda juda qulay — destructuring bilan kalit va qiymatni bir vaqtda olish mumkin:

for (const [kalit, qiymat] of Object.entries(foydalanuvchi)) {
  console.log(`${kalit}: ${qiymat}`);
}
// ism: Jasur
// yosh: 24
// shahar: Toshkent

Object.keys, values, entries — qachon qaysi?

const mahsulot = { nomi: "Telefon", narxi: 3000000, omborda: true };

// Faqat kalitlar kerak bo'lsa
Object.keys(mahsulot);    // ["nomi", "narxi", "omborda"]

// Faqat qiymatlar kerak bo'lsa
Object.values(mahsulot);  // ["Telefon", 3000000, true]

// Ikkalasi bir vaqtda kerak bo'lsa
Object.entries(mahsulot); // [["nomi","Telefon"], ["narxi",3000000], ["omborda",true]]

Object.assign — ob'ektlarni birlashtirish

Object.assign(maqsad, manba1, manba2, ...) — bir yoki bir nechta manba ob'ektning xususiyatlarini maqsad ob'ektga ko'chiradi va maqsad ob'ektni qaytaradi.

const asosiy = { ism: "Jasur", yosh: 24 };
const qoshimcha = { shahar: "Toshkent", kasb: "Dasturchi" };

const natija = Object.assign(asosiy, qoshimcha);

console.log(natija);
// { ism: "Jasur", yosh: 24, shahar: "Toshkent", kasb: "Dasturchi" }

console.log(asosiy === natija); // true — maqsad ob'ekt o'zgartirildi

Muhim: Object.assign maqsad ob'ektni o'zgartiradi. Agar asl ob'ektni saqlab qolish kerak bo'lsa — maqsad sifatida bo'sh ob'ekt beriladi:

const asl = { ism: "Jasur", yosh: 24 };
const yangi = { shahar: "Toshkent" };

// Xato — asl ob'ekt o'zgarib ketadi
const natija1 = Object.assign(asl, yangi);

// To'g'ri — asl ob'ekt saqlanadi
const natija2 = Object.assign({}, asl, yangi);

console.log(asl);     // { ism: "Jasur", yosh: 24 } — o'zgarmadi
console.log(natija2); // { ism: "Jasur", yosh: 24, shahar: "Toshkent" }

Bir xil kalit bo'lsa — oxirgisi ustun keladi

const standart = { rang: "qora", hajm: "M", narx: 100000 };
const maxsus   = { rang: "oq", narx: 150000 };

const natija = Object.assign({}, standart, maxsus);
console.log(natija);
// { rang: "oq", hajm: "M", narx: 150000 }
// rang va narx maxsus dan keldi — u keyinroq yozilgan

Amalda Object.assign ko'pincha standart sozlamalarni foydalanuvchi sozlamalari bilan birlashtirish uchun ishlatiladi:

const standartSozlamalar = {
  til: "uz",
  mavzu: "yorug",
  bildirishnomalar: true,
  sahifadagiSon: 10
};

function sozlamalarniYukla(foydalanuvchiSozlamalari) {
  return Object.assign({}, standartSozlamalar, foydalanuvchiSozlamalari);
}

const mySozlamalar = sozlamalarniYukla({ mavzu: "qorong'u", sahifadagiSon: 20 });
console.log(mySozlamalar);
// { til: "uz", mavzu: "qorong'u", bildirishnomalar: true, sahifadagiSon: 20 }

Object.freeze — ob'ektni qulflash

Object.freeze() ob'ektni "muzlatadi" — undan keyin xususiyat qo'shib, o'zgartirib yoki o'chirib bo'lmaydi.

const sozlamalar = Object.freeze({
  versiya: "1.0.0",
  maxsiyYol: "/api/v1",
  maksimalUrinish: 3
});

sozlamalar.versiya = "2.0.0";      // ishlaydi, lekin o'zgarmaydi
sozlamalar.yangi = "qiymat";       // ishlaydi, lekin qo'shilmaydi
delete sozlamalar.maksimalUrinish; // ishlaydi, lekin o'chirilmaydi

console.log(sozlamalar);
// { versiya: "1.0.0", maxsiyYol: "/api/v1", maksimalUrinish: 3 }
// Hech narsa o'zgarmadi

"use strict" rejimida esa muzlatilgan ob'ektni o'zgartirishga urinish xato tashlab beradi:

"use strict";

const sozlamalar = Object.freeze({ versiya: "1.0.0" });

sozlamalar.versiya = "2.0.0";
// TypeError: Cannot assign to read only property 'versiya'

Nima uchun freeze kerak?

Tasavvur qiling: loyihaning turli joylarida ishlatiladigan konfiguratsiya ob'ekti bor. Biror dasturchi xato qilib uni o'zgartirib yuborsa — butun loyiha noto'g'ri ishlaydi. Object.freeze buni oldini oladi.

const DB_CONFIG = Object.freeze({
  host: "localhost",
  port: 5432,
  database: "myapp"
});

// Loyihaning istalgan joyida DB_CONFIG ishlatiladi
// Hech kim uni tasodifan o'zgartira olmaydi

freeze — faqat birinchi qatlam

Object.freeze faqat ob'ektning o'zini muzlatadi — ichidagi ob'ektlarni emas.

const konfiguratsiya = Object.freeze({
  server: {
    port: 3000,
    host: "localhost"
  },
  versiya: "1.0"
});

konfiguratsiya.versiya = "2.0";   // ishlamaydi — muzlatilgan
konfiguratsiya.server.port = 8080; // ishlaydi! ichki ob'ekt muzlatilmagan

console.log(konfiguratsiya.server.port); // 8080

Ichki ob'ektlarni ham muzlatish uchun har birini alohida freeze qilish kerak.


Object.fromEntries — entries dan ob'ekt yasash

Object.entries ning teskarisi — [kalit, qiymat] juftliklari massividan ob'ekt yasaydi.

const juftliklar = [["ism", "Jasur"], ["yosh", 24], ["shahar", "Toshkent"]];

const ob'ekt = Object.fromEntries(juftliklar);
console.log(ob'ekt);
// { ism: "Jasur", yosh: 24, shahar: "Toshkent" }

Object.entries + map + Object.fromEntries — ob'ektning qiymatlarini o'zgartirish uchun qulay kombinatsiya:

const narxlar = { noutbuk: 8000000, sichqoncha: 150000, klaviatura: 300000 };

// Barcha narxlarga 10% chegirma
const chegirmaLiNarxlar = Object.fromEntries(
  Object.entries(narxlar).map(([mahsulot, narx]) => [mahsulot, narx * 0.9])
);

console.log(chegirmaLiNarxlar);
// { noutbuk: 7200000, sichqoncha: 135000, klaviatura: 270000 }

Tez-tez uchraydigan xatolar

Object.assign da maqsad ob'ektni o'zgartirish

const foydalanuvchi = { ism: "Jasur" };
const yangilash = { yosh: 25 };

// Xato — foydalanuvchi o'zgarib ketadi
Object.assign(foydalanuvchi, yangilash);
console.log(foydalanuvchi); // { ism: "Jasur", yosh: 25 } — o'zgardi

// To'g'ri — asl ob'ekt saqlanadi
const yangi = Object.assign({}, foydalanuvchi, yangilash);
console.log(foydalanuvchi); // { ism: "Jasur" } — o'zgarmadi

freeze chuqur ishlamaydi deb bilmaslik

const config = Object.freeze({
  db: { port: 5432 } // bu ichki ob'ekt muzlatilmagan
});

config.db.port = 9999; // o'zgaradi — bu xato!

Chuqur muzlatish kerak bo'lsa — kutubxona (masalan deepFreeze) yoki rekursiv yechim ishlatiladi.

Object.keys ni ob'ekt o'rniga boshqa turga qo'llash

// Xato — null ga qo'llanishi xato beradi
Object.keys(null); // TypeError

// To'g'ri — avval tekshirish
const ob'ekt = null;
if (ob'ekt) {
  Object.keys(ob'ekt);
}

Xulosa

Object.keys — kalitlar massivi. Xususiyatlar sonini bilish, kalitlar ustida aylanish uchun.

Object.values — qiymatlar massivi. Qiymatlarni hisoblash, filtrlash uchun.

Object.entries — [kalit, qiymat] juftliklari massivi. Ikkalasi bir vaqtda kerak bo'lganda. Object.fromEntries bilan birgalikda ob'ektni transform qilish uchun.

Object.assign — ob'ektlarni birlashtirish. Asl ob'ektni saqlab qolish uchun birinchi argument {} bo'lishi kerak.

Object.freeze — ob'ektni o'zgartirib bo'lmaydigan qilish. Faqat birinchi qatlam muzlatiladi — ichki ob'ektlar emas.


Keyingi dars

20-dars: Destructuring — ob'ekt va massiv