kodingup.camp

Beranda/JavaScript Mastery: Object & Data

Manipulasi Object Tingkat Lanjut

Modul 1 dari 144 menit bacaAdvanced object manipulation

Isi modul

    Kenapa ini penting

    Bayangkan kamu membuat aplikasi toko online. Satu produk punya nama, harga, stok, kategori, dan foto. Satu pengguna punya nama, email, alamat, dan riwayat pesanan. Semua itu disimpan sebagai object. Setiap hari kodemu akan menggabungkan object (misalnya data default + data dari form), menyalin object (supaya data asli tidak rusak), membaca semua kuncinya (untuk membuat tabel), dan membuat kunci secara dinamis (misalnya dari nama kolom yang dipilih pengguna).

    Kalau kamu tidak paham cara menyalin object dengan benar, kamu akan bertemu bug klasik: "Kok data di keranjang A ikut berubah waktu saya ubah keranjang B?" Bug seperti ini susah dilacak karena kodenya kelihatan benar. Modul ini membekali kamu dengan alat-alat modern untuk mengolah object tanpa jebakan semacam itu.

    Konsep inti

    Object literal, shorthand, dan computed property

    Object literal adalah cara menulis object langsung dengan kurung kurawal {}. Ada beberapa fitur yang membuat penulisannya lebih ringkas:

    Analogi computed property: kamu punya lemari arsip dan label laci ditulis berdasarkan nama bulan yang sedang berjalan. Labelnya tidak ditentukan dari awal, tapi dihitung saat itu juga.

    Membaca isi object: keys, values, entries

    Tiga method statis ini mengubah object menjadi array, sehingga kamu bisa memakai loop atau method array:

    Method Hasil Contoh hasil untuk {a: 1, b: 2}
    Object.keys(obj) array kunci ['a', 'b']
    Object.values(obj) array nilai [1, 2]
    Object.entries(obj) array pasangan [kunci, nilai] [['a', 1], ['b', 2]]

    Ketiganya hanya mengambil properti milik object itu sendiri (own property) yang enumerable (bisa dihitung), dan tidak mengambil kunci berupa Symbol (dibahas di modul 5).

    Menggabungkan object: spread dan Object.assign

    Spread syntax ... "menumpahkan" isi object ke object baru. { ...a, ...b } membuat object baru berisi semua properti a, lalu ditimpa oleh properti b kalau ada kunci yang sama. Urutan penting: yang ditulis belakangan menang.

    Object.assign(target, sumber1, sumber2) melakukan hal serupa, tapi mengubah target secara langsung dan mengembalikan target itu. Kalau kamu tidak ingin mengubah object yang sudah ada, pakai Object.assign({}, a, b) atau lebih sederhana pakai spread.

    Shallow copy vs deep copy

    Ini konsep paling penting di modul ini. Object disimpan sebagai referensi (alamat). Saat kamu menulis const b = a, kamu tidak menyalin object, kamu hanya memberi nama kedua ke alamat yang sama. Mirip memberi kunci duplikat rumah ke teman: rumahnya tetap satu.

    structuredClone bisa menyalin Date, Map, Set, array, dan object bersarang, bahkan referensi melingkar. Tapi ia tidak bisa menyalin function (akan melempar error DataCloneError) dan tidak membawa prototype class (hasilnya object biasa). Trik lama JSON.parse(JSON.stringify(obj)) juga deep copy, tapi merusak Date menjadi string, membuang undefined dan function, dan gagal pada Map/Set.

    Contoh kode

    // 1) Shorthand dan computed property
    const nama = "Kopi Susu";
    const harga = 18000;
    const kolomDiskon = "diskon_" + "member"; // kunci dihitung saat runtime
    
    const produk = {
      nama,              // sama dengan nama: nama
      harga,             // sama dengan harga: harga
      [kolomDiskon]: 10, // kuncinya jadi "diskon_member"
      info() {           // method shorthand
        return `${this.nama} - Rp${this.harga}`;
      },
    };
    console.log(produk.diskon_member); // → 10
    console.log(produk.info());        // → Kopi Susu - Rp18000
    
    // 2) keys, values, entries
    const stok = { kopi: 12, teh: 0, coklat: 5 };
    console.log(Object.keys(stok));   // → [ 'kopi', 'teh', 'coklat' ]
    console.log(Object.values(stok)); // → [ 12, 0, 5 ]
    for (const [item, jumlah] of Object.entries(stok)) {
      console.log(`${item}: ${jumlah > 0 ? "tersedia" : "habis"}`);
    }
    // → kopi: tersedia
    // → teh: habis
    // → coklat: tersedia
    
    // 3) Menggabungkan pengaturan default dengan pilihan pengguna
    const defaultSetting = { tema: "terang", bahasa: "id", notifikasi: true };
    const pilihanUser = { tema: "gelap" };
    const setting = { ...defaultSetting, ...pilihanUser };
    console.log(setting); // → { tema: 'gelap', bahasa: 'id', notifikasi: true }
    
    const target = { a: 1 };
    const hasil = Object.assign(target, { b: 2 });
    console.log(target, hasil === target); // → { a: 1, b: 2 } true  (target ikut berubah!)
    
    // 4) Shallow copy: bagian dalam masih berbagi alamat
    const pesanan = { id: 1, alamat: { kota: "Bandung" } };
    const salinanDangkal = { ...pesanan };
    salinanDangkal.id = 2;
    salinanDangkal.alamat.kota = "Jakarta";
    console.log(pesanan.id);          // → 1        (lapisan luar aman)
    console.log(pesanan.alamat.kota); // → Jakarta  (lapisan dalam ikut berubah!)
    
    // 5) Deep copy dengan structuredClone
    const asli = { id: 1, alamat: { kota: "Bandung" }, dibuat: new Date(0), tag: new Set(["baru"]) };
    const salinanDalam = structuredClone(asli);
    salinanDalam.alamat.kota = "Surabaya";
    console.log(asli.alamat.kota);                    // → Bandung (aman)
    console.log(salinanDalam.dibuat instanceof Date); // → true
    console.log(salinanDalam.tag.has("baru"));        // → true
    
    // 6) Bandingkan dengan trik JSON yang merusak tipe data
    const viaJson = JSON.parse(JSON.stringify(asli));
    console.log(typeof viaJson.dibuat); // → string  (Date berubah jadi teks)
    console.log(viaJson.tag);           // → {}      (Set hilang isinya)
    
    // 7) structuredClone tidak bisa menyalin function
    try {
      structuredClone({ hitung() {} });
    } catch (err) {
      console.log(err.name); // → DataCloneError
    }
    

    Kesalahan umum

    1. Mengira const b = a itu menyalin. Itu hanya menyalin alamat. Pakai { ...a } untuk salinan dangkal atau structuredClone(a) untuk salinan dalam.
    2. Memakai spread untuk object bersarang lalu kaget data asli berubah. Spread hanya menyalin lapisan pertama. Kalau ada object di dalam object dan kamu akan mengubah bagian dalamnya, pakai structuredClone.
    3. Salah urutan saat menggabungkan. { ...pilihanUser, ...defaultSetting } membuat default menimpa pilihan pengguna. Taruh yang ingin "menang" di paling belakang.
    4. Lupa kurung siku pada computed property. { kolom: 1 } menghasilkan kunci bernama "kolom". Untuk memakai isi variabel, tulis { [kolom]: 1 }.
    5. Object.assign(a, b) tanpa sadar mengubah a. Kalau a adalah data dari luar (misalnya props atau state), ini bisa menimbulkan bug. Pakai Object.assign({}, a, b) atau spread.

    Latihan

    1. Mudah, Diberikan const nilai = { budi: 80, sari: 92, joko: 75 }. Cetak total semua nilai memakai Object.values.
    2. Sedang, Buat function setField(obj, kunci, nilai) yang mengembalikan object baru dengan kunci dinamis tersebut ditambahkan atau diganti, tanpa mengubah object asli.
    3. Menantang, Diberikan object profil bersarang (berisi alamat dan hobi berupa array). Buat salinan yang aman, ubah kota dan tambahkan satu hobi pada salinan, lalu buktikan dengan console.log bahwa object asli tidak berubah.
    Lihat solusi
    // 1) Mudah
    const nilai = { budi: 80, sari: 92, joko: 75 };
    let total = 0;
    for (const n of Object.values(nilai)) total += n;
    console.log(total); // → 247
    
    // 2) Sedang
    function setField(obj, kunci, nilai) {
      return { ...obj, [kunci]: nilai };
    }
    const awal = { a: 1 };
    const baru = setField(awal, "b", 2);
    console.log(awal, baru); // → { a: 1 } { a: 1, b: 2 }
    
    // 3) Menantang
    const profil = { nama: "Rina", alamat: { kota: "Medan" }, hobi: ["baca"] };
    const salinan = structuredClone(profil);
    salinan.alamat.kota = "Padang";
    salinan.hobi.push("renang");
    console.log(profil.alamat.kota, profil.hobi);   // → Medan [ 'baca' ]
    console.log(salinan.alamat.kota, salinan.hobi); // → Padang [ 'baca', 'renang' ]
    

    Ringkasan

    Kuis pemahaman

    Pilih satu jawaban per soal. Penjelasan muncul setelah kamu menjawab.