Objek JavaScript Lanjutan: Method, Referensi, dan Iterasi

Melangkah lebih jauh dari dasar objek — key dinamis, method dan this, menyalin vs mereferensikan, Object.keys/values/entries, membekukan objek, dan pola yang kamu pakai tiap hari di kode nyata.

Diterbitkan 2 Agustus 202613 menit bacaOleh ACY Partner Indonesia
Objek JavaScript lanjutan — key, method, referensi, dan iterasi
300 × 250Slot Iklan TersediaPasang iklan Anda di sini

Kamu sudah kenal bentuk dasar sebuah objek: kurung kurawal, beberapa nilai berlabel di dalamnya, dan dot notation untuk membacanya. Bekal segitu memang cukup untuk mulai, dan itu sudah kita bahas di artikel array dan objek. Tapi objek adalah tulang punggung hampir semua yang kamu bangun di JavaScript, dan begitu kamu mulai menulis kode betulan, muncul pertanyaan-pertanyaan yang nggak terjawab oleh materi dasar. Gimana caranya membaca key yang namanya baru ketahuan saat program berjalan? Kenapa menyalin objek kadang nggak benar-benar menyalin? Gimana cara me-looping isi sebuah objek? Lalu, apa artinya kalau sebuah objek punya method?

Artikel ini mengupas semua itu. Setelah selesai, pemahamanmu soal objek bakal cukup matang untuk membaca kode orang lain tanpa pusing, sekaligus menghindari segelintir jebakan halus yang hampir pasti menjerat tiap orang pada suatu titik.

Dua cara membaca dan menulis property

Dot notation adalah cara sehari-hari untuk mengakses isi objek, dan inilah yang sebaiknya jadi pilihan utamamu karena terbaca rapi:

const pengguna = {
  nama: "John Doe",
  umur: 28,
};

console.log(pengguna.nama);   // "John Doe"
pengguna.umur = 29;          // ubah nilai
pengguna.kota = "Jakarta";    // tambah property baru

Tapi ada cara kedua: bracket notation, ditulis dengan kurung siku dan key berupa string. Hasilnya sama persis — sampai pada titik tertentu, karena kurung siku bisa melakukan sesuatu yang dot notation jelas nggak bisa.

console.log(pengguna["nama"]);   // "John Doe" — sama dengan pengguna.nama

Sejauh ini memang kelihatan cuma lebih panjang. Bedanya muncul karena yang ada di dalam kurung siku itu sebuah ekspresi. Isinya bisa berupa variabel, yang artinya kamu bisa membaca property yang namanya baru kamu ketahui ketika program berjalan:

const field = "umur";
console.log(pengguna[field]);   // 28 — membaca property "umur"

// Ini beda dengan dot notation yang sifatnya harfiah:
console.log(pengguna.field);    // undefined — mencari key yang namanya persis "field"

Di sinilah letak perbedaan yang penting. pengguna.field mencari property yang namanya benar-benar field. Sementara pengguna[field] mengevaluasi field dulu (jadi string "umur") lalu mencari hasil itu. Kapan pun key-nya datang dari variabel, input pengguna, atau perulangan, kamu butuh kurung siku.

Saat kamu wajib pakai kurung siku

Bracket notation bukan cuma soal variabel — ini juga satu-satunya cara menjangkau key yang bukan identifier yang valid. Key yang mengandung spasi atau tanda hubung ({ "nama depan": "John" }), atau key yang murni angka, nggak bisa ditulis pakai titik: pengguna.nama depan langsung jadi syntax error. Mau nggak mau kamu harus menulis pengguna["nama depan"]. Jadi patokan gampangnya begini: pakai dot notation sebagai default karena lebih enak dibaca, dan beralih ke kurung siku saat key-nya dinamis atau punya nama yang nggak biasa.

Computed property name

Kurung siku juga berlaku saat kamu menulis objek literal, bukan cuma saat membacanya. Membungkus sebuah key dengan kurung siku di dalam { } memungkinkan kamu menghitung nama key dari sebuah variabel — ini namanya computed property name:

const key = "status";

const order = {
  id: 101,
  [key]: "dikirim",   // key-nya jadi "status"
};

console.log(order.status);   // "dikirim"

Tanpa kurung siku, key: "dikirim" bakal membuat property yang namanya benar-benar key. Dengan kurung siku, JavaScript mengevaluasi variabelnya dulu lalu memakai nilainya sebagai nama property. Pola ini bakal sering kamu lihat di kode yang membangun objek secara dinamis — misalnya saat mengubah sederet field menjadi sebuah objek.

Shorthand property

Kalau nama sebuah variabel sama dengan nama key yang kamu inginkan, ES2015 mengizinkanmu melewati pengulangan. Daripada menulis nama: nama, kamu cukup menulis nama sekali:

const nama = "Jane Doe";
const umur = 34;

// Cara panjang:
const penggunaA = { nama: nama, umur: umur };

// Shorthand — hasilnya identik:
const penggunaB = { nama, umur };

console.log(penggunaB);   // { nama: "Jane Doe", umur: 34 }

Ini murni soal kepraktisan, tapi kamu bakal menemuinya di mana-mana pada kode modern, terutama saat sebuah fungsi mengembalikan objek. Pola ini pas banget dengan fungsi yang mengumpulkan beberapa nilai lalu mengembalikannya dalam bentuk objek yang ringkas.

Method: fungsi yang tinggal di dalam objek

Nilai sebuah property bisa apa saja — number, string, array, bahkan objek lain. Nilai itu juga bisa berupa fungsi. Fungsi yang disimpan sebagai property dari sebuah objek disebut method, dan method adalah cara objek melakukan sesuatu, bukan sekadar menyimpan sesuatu.

const kalkulator = {
  total: 0,
  tambah(jumlah) {
    this.total += jumlah;
  },
  reset() {
    this.total = 0;
  },
};

kalkulator.tambah(50);
kalkulator.tambah(30);
console.log(kalkulator.total);   // 80

Penulisan tambah(jumlah) { ... } adalah bentuk shorthand modern untuk mendefinisikan method (sama saja dengan tambah: function(jumlah) { ... }, cuma lebih ringkas). Cara memanggil method persis seperti yang kamu bayangkan: objek.method(argumen).

Keyword this di dalam method

Perhatikan this.total di contoh tadi. Di dalam sebuah method, this merujuk ke objek tempat method itu dipanggil — jadi this.total berarti “property total dari objek yang aku jadi method-nya.” Begitulah tambah tahu total yang mana yang harus diperbarui.

const akun = {
  pemilik: "John Doe",
  saldo: 1000,
  deskripsi() {
    return `${this.pemilik} punya saldo ${this.saldo}`;
  },
};

console.log(akun.deskripsi());   // "John Doe punya saldo 1000"

this adalah salah satu sudut JavaScript yang paling bikin pusing, dan perilakunya sepenuhnya bergantung pada bagaimana sebuah fungsi dipanggil, bukan di mana ia didefinisikan. Cerita lengkapnya layak dapat artikel sendiri, tapi untuk method biasa yang dipanggil sebagai objek.method(), aturannya sederhana: this adalah objek yang ada sebelum tanda titik.

Arrow function nggak punya this sendiri

Ada satu jebakan yang perlu ditandai sejak sekarang. Kalau kamu mendefinisikan method memakai arrow function, ia nggak akan mengikat this ke objeknya — arrow function justru mewarisi this dari scope di sekelilingnya. Jadi deskripsi: () => this.pemilik di dalam objek biasanya bakal memberimu undefined, bukan nama pemilik. Untuk method yang butuh this menunjuk ke objeknya, pakai bentuk shorthand deskripsi() { ... }, jangan arrow. Simpan arrow untuk callback yang memang kamu inginkan tetap memegang this dari luar.

Objek disalin berdasarkan referensi, bukan nilai

Ini hal paling penting — sekaligus paling mengejutkan — soal objek, dan inilah yang paling sering bikin orang bingung di seluruh daftar ini. Saat kamu menugaskan sebuah objek ke variabel baru, kamu tidak mendapat salinan objek itu. Yang kamu dapat adalah nama kedua yang menunjuk ke objek yang sama.

const asli = { jumlah: 1 };
const salinan = asli;   // BUKAN salinan — objek yang sama, dua nama

salinan.jumlah = 99;

console.log(asli.jumlah);   // 99 — yang asli ikut berubah!

Baik asli maupun salinan adalah label yang menempel pada satu objek yang sama di baliknya. Ubah lewat label mana pun, perubahannya muncul lewat keduanya. Inilah yang dimaksud “objek disimpan berdasarkan referensi”, dan ini benar-benar beda dari cara kerja tipe primitif (number, string, boolean) — yang justru disalin berdasarkan nilainya:

let a = 5;
let b = a;   // b adalah salinan asli yang mandiri
b = 10;
console.log(a);   // 5 — nggak terpengaruh

Perilaku referensi yang sama juga berlaku saat kamu mengoper objek ke dalam sebuah fungsi: fungsi itu menerima referensi ke objek yang sama, sehingga perubahan yang ia lakukan terlihat oleh pemanggilnya. Array juga bekerja begini, sebab di balik layar array sebenarnya juga objek.

Membuat salinan sungguhan: spread dan Object.assign

Kalau kamu benar-benar mau salinan yang mandiri, kamu harus memintanya secara eksplisit. Cara modern yang paling bersih adalah operator spread (...), yang menyalin semua property sebuah objek ke dalam objek yang baru:

const asli = { jumlah: 1, label: "a" };
const salinanAsli = { ...asli };

salinanAsli.jumlah = 99;

console.log(asli.jumlah);        // 1 — kali ini nggak tersentuh
console.log(salinanAsli.jumlah); // 99

Object.assign({}, asli) melakukan tugas yang sama, dan kamu masih akan menemuinya di kode lama:

const salinanAsli = Object.assign({}, asli);

Spread juga memudahkanmu menyalin sekaligus mengubah dalam satu langkah, sebuah pola yang super umum (begini cara update state bekerja di framework seperti React):

const diperbarui = { ...asli, jumlah: 2 };
// semua property dari asli, tapi jumlah ditimpa jadi 2

Spread itu salinan dangkal — objek bersarang tetap berbagi

Ini jebakan yang menjerat orang justru setelah mereka belajar soal spread: ia cuma menyalin satu tingkat ke dalam. Kalau sebuah property isinya objek atau array lagi, salinannya bakal memegang referensi yang sama ke objek bersarang itu, bukan salinannya. Jadi const salinan = { ...pengguna } lalu salinan.alamat.kota = "Bandung" juga akan mengubah pengguna.alamat.kota, karena kedua objek menunjuk ke alamat yang sama. Untuk salinan dalam (deep copy) yang benar-benar mandiri, pakai structuredClone(asli) di lingkungan modern, atau fungsi dari sebuah library. Yang penting kamu ingat: { ...obj } dan Object.assign itu dangkal — sempurna untuk objek datar, tapi jebakan untuk objek bersarang.

Me-looping sebuah objek

Array punya index, jadi perulangan for bisa menyusurinya dengan mulus. Objek justru punya key bernama, sehingga mengiterasinya butuh pendekatan berbeda. Tiga method andalan berikut mengubah isi objek menjadi array yang bisa kamu looping dengan alat array yang sudah kamu kuasai.

Object.keys() memberimu array berisi key-nya, Object.values() memberimu nilai-nilainya, dan Object.entries() memberimu keduanya sebagai pasangan [key, value]:

const nilai = {
  matematika: 90,
  sains: 85,
  sejarah: 78,
};

console.log(Object.keys(nilai));     // ["matematika", "sains", "sejarah"]
console.log(Object.values(nilai));   // [90, 85, 78]
console.log(Object.entries(nilai));  // [["matematika", 90], ["sains", 85], ["sejarah", 78]]

Karena masing-masing mengembalikan array sungguhan, kamu bisa merangkainya dengan forEach, map, atau metode array mana pun yang sudah kamu pelajari:

Object.entries(nilai).forEach(([mapel, skor]) => {
  console.log(`${mapel}: ${skor}`);
});
// matematika: 90
// sains: 85
// sejarah: 78

Bagian [mapel, skor] di dalam callback itu adalah array destructuring — ia mengeluarkan dua elemen dari tiap pasangan ke variabel bernama. Begitu kamu terbiasa, ini terbaca enak banget.

Perulangan for…in

Ada juga perulangan khusus untuk objek, yaitu for...in, yang mengiterasi key sebuah objek secara langsung. Ia berfungsi, tapi punya sisi tajam yang perlu kamu tahu:

for (const key in nilai) {
  console.log(key, nilai[key]);
}

Utamakan Object.keys/entries ketimbang for...in

for...in menyusuri bukan cuma key milik objeknya sendiri, tapi juga key apa pun yang diwarisi dari rantai prototype-nya, yang bisa mengejutkanmu dengan property yang nggak pernah kamu taruh di situ. Object.keys() dan Object.entries() hanya mengembalikan property milik objek itu sendiri, jadi lebih bisa ditebak dan langsung memberimu array normal yang bisa kamu map dan filter. Untuk iterasi objek sehari-hari, andalkan Object.entries(obj).forEach(...) lebih dulu. Kalau suatu saat kamu memang pakai for...in, jaga dengan Object.hasOwn(obj, key) untuk melewati key warisan.

Memeriksa apakah sebuah property ada

Mengakses property yang nggak ada akan mengembalikan undefined, bukan melempar error. Ini memang praktis, tapi bisa menyembunyikan bug. Beberapa cara bersih untuk memeriksa keberadaan property:

const pengguna = { nama: "John Doe", umur: 28 };

console.log("nama" in pengguna);          // true — operator `in`
console.log("email" in pengguna);         // false
console.log(Object.hasOwn(pengguna, "umur"));   // true — modern, khusus property sendiri
console.log(pengguna.email !== undefined);      // false — juga berhasil

Operator in singkat dan enak dibaca. Object.hasOwn() adalah pilihan modern yang andal saat kamu memang mau mengabaikan property warisan. Membandingkan terhadap undefined memang berfungsi, tapi sedikit rapuh — property yang isinya benar-benar undefined bakal terbaca seolah “tidak ada”, padahal biasanya bukan itu maksudmu.

Optional chaining: menjangkau objek bersarang dengan aman

Data nyata bersarang dalam-dalam, dan menjangkau lewat serangkaian property jadi berisiko kalau salah satu bagian di tengahnya mungkin nggak ada. Mengakses property pada undefined akan melempar error dan mematikan baris itu:

const order = { id: 1 };   // nggak ada `pelanggan` di sini

// console.log(order.pelanggan.nama);   // TypeError: Cannot read properties of undefined

Optional chaining (?.) menyelesaikan ini dengan rapi. Kalau nilai sebelum ?. adalah null atau undefined, seluruh ekspresinya langsung berhenti dan menghasilkan undefined, bukan melempar error:

console.log(order.pelanggan?.nama);   // undefined — nggak crash

const lengkap = {
  pelanggan: { nama: "Jane Doe", alamat: { kota: "Jakarta" } },
};
console.log(lengkap.pelanggan?.alamat?.kota);   // "Jakarta"

Ia berpasangan secara alami dengan operator nullish coalescing (??) untuk menyediakan nilai cadangan saat ada yang hilang:

const kota = order.pelanggan?.alamat?.kota ?? "Tidak diketahui";
console.log(kota);   // "Tidak diketahui"

Dua operator ini diam-diam jadi salah satu fitur paling sering dipakai di JavaScript modern, justru karena keduanya membuat pekerjaan dengan data yang berantakan dan terisi separuh-separuh jadi nggak menyakitkan.

Membekukan objek agar tak bisa diubah

Secara default tiap objek itu bisa diubah — siapa pun yang memegang referensinya bisa mengubahnya. Saat kamu ingin mengunci sebuah objek supaya nggak bisa dimodifikasi, Object.freeze() melakukan persis itu:

const config = Object.freeze({
  apiUrl: "https://api.example.com",
  timeout: 5000,
});

config.timeout = 9000;    // diabaikan diam-diam (atau melempar error di strict mode)
console.log(config.timeout);   // 5000 — nggak berubah

Ini berguna untuk objek konfigurasi dan konstanta yang nggak ingin kamu sentuh sama sekali. Dua catatan: percobaan mengubahnya gagal diam-diam kecuali kodemu berjalan di strict mode (di situ ia melempar error), dan seperti spread, pembekuan ini sifatnya dangkal — objek bersarang di dalam objek yang dibekukan tetap bisa diubah. Untuk kebanyakan kebutuhan config, freeze yang dangkal sudah lebih dari cukup.

Contoh realistis

Coba kita rangkai semua kepingannya jadi sesuatu yang mendekati kode nyata — sebuah order kecil dengan method, key dinamis, dan akses yang aman:

function buatOrder(pelanggan, items) {
  return {
    pelanggan,                          // shorthand property
    items,
    get jumlahItem() {                  // accessor terhitung
      return this.items.length;
    },
    total() {                           // method yang memakai `this`
      return this.items.reduce((sum, item) => sum + item.harga, 0);
    },
  };
}

const order = buatOrder("Jane Doe", [
  { nama: "Keyboard", harga: 250000 },
  { nama: "Mouse", harga: 120000 },
]);

console.log(order.pelanggan);    // "Jane Doe"
console.log(order.jumlahItem);   // 2
console.log(order.total());      // 370000

// membaca dengan aman sesuatu yang mungkin nggak ada:
console.log(order.kupon?.kode ?? "tanpa kupon");   // "tanpa kupon"

Satu fungsi pabrik ini memakai shorthand property, sebuah method yang bersandar pada this, sebuah getter, dan optional chaining di sisi pemanggilnya — semua ide dari artikel ini bekerja bareng persis seperti di kode sehari-hari.

Sedikit catatan soal bekerja dengan JSON

Objek juga jadi cara kamu menangani data yang datang dari API atau yang disimpan ke storage. Data semacam itu bepergian dalam bentuk JSON — teks yang tampilannya mirip objek JavaScript — dan kamu mengonversinya bolak-balik dengan JSON.parse (teks ke objek) dan JSON.stringify (objek ke teks). Saat kamu perlu memeriksa atau merapikan teks itu, sebuah JSON formatter bikin tumpukan data yang sudah dimampatkan jadi terbaca dalam hitungan detik. Kita bakal membahas JSON secara tuntas di artikelnya sendiri — untuk sekarang, ketahui saja bahwa keterampilan objek yang sedang kamu bangun di sini persis itulah yang bakal kamu pakai begitu data nyata muncul.

Penutup

Kamu sudah melaju jauh melampaui dasar-dasar objek:

  • Bracket notation (obj[key]) membaca property dengan key yang dinamis atau tak biasa; dot notation adalah default yang enak dibaca untuk key yang tetap.
  • Computed property name ([key]: value) dan shorthand ({ nama }) membuat penyusunan objek jadi ringkas.
  • Fungsi yang disimpan di sebuah objek disebut method, dan this di dalamnya menunjuk ke objek tempat ia dipanggil — tapi arrow function nggak mengikat this, jadi pakai bentuk method shorthand.
  • Objek dipegang berdasarkan referensi — menugaskannya nggak menyalinnya. Pakai spread ({ ...obj }) atau Object.assign untuk salinan dangkal, dan structuredClone untuk salinan dalam.
  • Iterasi pakai Object.keys / values / entries, yang mengembalikan array sehingga bisa dipakai dengan metode array; utamakan ketiganya ketimbang for...in.
  • Periksa keberadaan property dengan in atau Object.hasOwn, jangkau data bersarang dengan aman lewat ?. dan ??, serta kunci objek dengan Object.freeze saat dibutuhkan.

Objek, berbarengan dengan metode array dari artikel sebelumnya, adalah dua paruh dari cara JavaScript menyimpan dan membentuk data. Dengan bekal referensi, penyalinan, dan iterasi, kamu sudah siap menyambut sintaks yang bikin proses mengeluarkan nilai dari objek dan array jadi nyaris tanpa usaha — yaitu destructuring, yang jadi bahasan berikutnya.

Tag:javascriptfrontendobjekreferensimenengah
728 × 90Slot Iklan TersediaPasang iklan Anda di sini

Artikel Terkait

Lihat Semua Artikel

Artikel yang Mungkin Kamu Suka

Apa Itu Framework Frontend? — chip kode dengan tag komponen
Frontend / Dasar

Apa Itu Framework Frontend?

Penjelasan ramah untuk pemula tentang apa itu framework frontend, kenapa mereka ada, masalah apa yang mereka selesaikan dibanding JavaScript biasa, dan kapan kamu memang sebaiknya memakainya.

20 Sep 20268 menit baca
Sampul fundamentals frontend bertuliskan Apa Itu Frontend dan HTML + CSS + JS
Frontend / Dasar

Apa Itu Frontend Development?

Panduan ramah pemula tentang frontend development: bagian website yang kamu lihat dan klik secara langsung. Pahami cara kerja HTML, CSS, dan JavaScript, serta bedanya frontend dengan backend.

20 Sep 20268 menit baca
Ilustrasi sampul untuk Apa yang Dikerjakan Frontend Developer
Frontend / Dasar

Apa yang Dikerjakan Frontend Developer: Panduan untuk Pemula

Penjelasan ramah pemula tentang apa yang sebenarnya dikerjakan frontend developer setiap hari: mengubah desain jadi antarmuka yang berfungsi, membangun UI yang bisa dipakai ulang, sampai urusan responsif, aksesibilitas, dan kecepatan.

20 Sep 20269 menit baca
Kartu judul bertuliskan Styling dan Interaktivitas di atas latar biru gelap ACY Partner
Frontend / Dasar

Cara Kerja Styling dan Interaktivitas

Penjelasan ramah pemula soal bagaimana CSS menyulap HTML polos jadi tampilan rapi, dan bagaimana JavaScript menambahkan perilaku — pola berpikir struktur, gaya, perilaku saat membangun halaman web.

20 Sep 20268 menit baca
Tiga lapisan front-end menyatu di satu halaman web
Frontend / Dasar

Cara HTML, CSS, dan JavaScript Bekerja Bersama

Panduan praktis untuk pemula: bikin satu tombol kecil, beri struktur dengan HTML, tampilan dengan CSS, dan perilaku dengan JavaScript, lalu lihat ketiga lapisan ini bekerja sama di halaman nyata.

20 Sep 20268 menit baca
Sampul ikhtisar praktik terbaik frontend
Frontend / Dasar

Ikhtisar Praktik Terbaik Frontend

Peta ringkas tentang apa itu frontend yang baik — HTML bermakna, CSS rapi, JavaScript secukupnya, desain responsif, performa, dan progressive enhancement, lengkap dengan arahan untuk mendalaminya.

20 Sep 20268 menit baca