Object adalah cara JavaScript mengelompokkan data yang saling berhubungan menjadi satu kesatuan bernama — seorang pengguna punya nama, email, dan peran; sebuah konfigurasi punya tema, bahasa, dan opsi notifikasi. Di aplikasi Node.js, object adalah format data paling dominan: hasil JSON.parse(), baris hasil query database, dan opsi konfigurasi module semuanya berbentuk object. Pada chapter ini kita akan membentuk object dengan property shorthand, membongkarnya dengan destructuring, menggabungkannya dengan spread, lalu mengakses data yang tidak pasti lengkap dengan optional chaining dan nullish coalescing dengan aman.

Property Shorthand dan Destructuring #

Sering kali kita punya variabel yang ingin dimasukkan ke object dengan nama property yang sama persis. ES 2015 memperbolehkan penulisan { nama, email } sebagai singkatan { nama: nama, email: email }. Sebaliknya, destructuring mengambil property object keluar ke variabel dengan satu baris — pola yang menggantikan akses berulang pengguna.nama, pengguna.email di setiap baris. Keduanya dirangkum dalam destructuring.mjs:

js
const nama = "Budi";
const email = "[email protected]";

// Property shorthand: nama property diambil dari nama variable
const pengguna = { nama, email, peran: "admin" };

// Destructuring dengan nama baru dan nilai bawaan
const { nama: namaPengguna, umur = 25 } = pengguna;

// Nested destructuring: ambil property di dalam property
const laporan = {
  judul: "Laporan Mingguan",
  penulis: { nama: "Siti", kota: "Bandung" },
};
const {
  penulis: { nama: namaPenulis, kota },
} = laporan;

console.log(`pengguna : ${pengguna.nama} <${pengguna.email}> peran ${pengguna.peran}`);
console.log(`ganti    : ${namaPengguna}, umur ${umur}`);
console.log(`penulis  : ${namaPenulis} dari ${kota}`);

Output yang Dihasilkan:

text
pengguna : Budi <[email protected]> peran admin
ganti    : Budi, umur 25
penulis  : Siti dari Bandung

Mari kita bedah pola-pola pada kode di atas:

  1. Baris 6 ({ nama, email, peran: "admin" }): nama dan email memakai shorthand, sementara peran ditulis lengkap karena nilainya bukan dari variabel bernama sama.
  2. Baris 9 (const { nama: namaPengguna, umur = 25 } = pengguna): property nama dibongkar ke variabel baru bernama namaPengguna. Property umur tidak ada di object, jadi nilai bawaan 25 yang dipakai.
  3. Baris 16-19 (nested destructuring): pola penulis: { nama: namaPenulis, kota } menelusuri dua lapis — ambil property penulis, lalu dari object tersebut ambil nama (di-rename) dan kota.

Destructuring juga bekerja pada parameter function, dan justru di situlah pola ini paling bersinar. Sebuah function yang menerima opsi seperti function buatServer({ host, port, debug = false }) bisa dipanggil dengan object bernama propertinya, sehingga urutan argumen tidak lagi relevan. Kita akan memakai pola ini terus-menerus saat berkenalan dengan API Express dan Fastify pada Section Framework dan Middleware.

Spread untuk Menggabungkan Object #

Operator spread ... “membentangkan” property sebuah object ke dalam object lain. Dua kegunaan utamanya: menggabungkan konfigurasi dengan aturan “yang belakangan menang”, dan menyalin object sebelum memodifikasinya agar data asli tetap utuh. Perhatikan spread.mjs:

js
const bawaan = { tema: "terang", bahasa: "id", notifikasi: true };
const pilihanPengguna = { tema: "gelap", notifikasi: false };

// Spread menggabungkan: property dari object di kanan menimpa yang di kiri
const pengaturan = { ...bawaan, ...pilihanPengguna };

// Salin object sebelum dimodifikasi agar object asli tidak berubah
const cadangan = { ...pengaturan };
cadangan.tema = "biru";

console.log(`tema          : ${pengaturan.tema}`);
console.log(`bahasa        : ${pengaturan.bahasa}`);
console.log(`notifikasi    : ${pengaturan.notifikasi}`);
console.log(`tema cadangan : ${cadangan.tema}`);
console.log(`tema asli     : ${pengaturan.tema}`);

Output yang Dihasilkan:

text
tema          : gelap
bahasa        : id
notifikasi    : false
tema cadangan : biru
tema asli     : gelap

Pembacaan hasilnya:

  1. Hasil gabungan: tema menjadi "gelap" karena pilihanPengguna berada di posisi kanan dan menimpa nilai bawaan; bahasa tetap "id" karena tidak pernah ditimpa.
  2. Salinan aman: mengubah cadangan.tema tidak menyentuh pengaturan.tema — keduanya adalah object berbeda. Tanpa spread, const cadangan = pengaturan hanya menyalin referensi sehingga mutasi pada satu sisi terlihat di sisi lain.

Optional Chaining dan Nullish Coalescing #

Data dari luar — berkas konfigurasi, API pihak ketiga, hasil query — tidak selalu lengkap. Optional chaining ?. membuat akses berantai berhenti dengan aman menghasilkan undefined alih-alih melempar TypeError di tengah jalan, dan nullish coalescing ?? menyediakan nilai cadangan hanya ketika operand kirinya null atau undefined. Berkas opsional.mjs memperlihatkan keduanya:

js
const pengguna = {
  nama: "Dewi",
  alamat: null,
  preferensi: { notifikasi: false },
};

// Optional chaining: akses berantai berhenti dengan aman saat bertemu null
const kota = pengguna.alamat?.kota;
const kodePos = pengguna.alamat?.kodePos ?? "tidak tercatat";

// Nullish coalescing: hanya mengganti nilai bila null atau undefined
const notifikasi = pengguna.preferensi?.notifikasi ?? true;

console.log(`kota       : ${kota}`);
console.log(`kode pos   : ${kodePos}`);
console.log(`notifikasi : ${notifikasi}`);

console.log("perbandingan || versus ??");
console.log(`  false || true -> ${false || true}`);
console.log(`  false ?? true -> ${false ?? true}`);

Output yang Dihasilkan:

text
kota       : undefined
kode pos   : tidak tercatat
notifikasi : false
perbandingan || versus ??
  false || true -> true
  false ?? true -> false

Tiga pengamatan dari output di atas:

  1. pengguna.alamat bernilai null, jadi pengguna.alamat?.kota langsung menghasilkan undefined tanpa pernah mencoba membaca .kota dari null.
  2. pengguna.preferensi?.notifikasi menghasilkan false — nilai yang sah. Berkat ??, nilai false ini dipertahankan, bukan diganti true.
  3. Baris terakhir memperlihatkan perbedaan krusial: false || true menghasilkan true karena || menganggap semua nilai falsy layak diganti, sedangkan false ?? true menghasilkan false. Inilah alasan ?? adalah pilihan yang benar untuk nilai boleh-false, "0", atau 0.

Menjelajah Isi Object #

Ketika nama property tidak bisa kita tulis satu per satu — misalnya property-nya dinamis — kita butuh cara memutar isi object. Tiga method statis Object menjadi andalan: Object.keys() mengembalikan array nama property, Object.values() mengembalikan array nilainya, dan Object.entries() mengembalikan array pasangan [nama, nilai]. Berkas menjelajah-object.mjs menerapkan ketiganya pada data stok:

js
const stok = {
  kopi: 12,
  teh: 30,
  susu: 8,
};

console.log(`keys   : ${Object.keys(stok).join(", ")}`);
console.log(`values : ${Object.values(stok).join(", ")}`);

let total = 0;
Object.entries(stok).forEach(([barang, jumlah]) => {
  console.log(`- ${barang}: ${jumlah} pcs`);
  total += jumlah;
});
console.log(`total  : ${total} pcs`);

Output yang Dihasilkan:

text
keys   : kopi, teh, susu
values : 12, 30, 8
- kopi: 12 pcs
- teh: 30 pcs
- susu: 8 pcs
total  : 50 pcs

Urutan yang tercetak bukan kebetulan: Object.keys(), Object.values(), dan Object.entries() mengikuti urutan property bernama string sesuai urutan penulisan, sehingga output-nya stabil dan bisa diandalkan. Callback forEach menerima setiap pasangan [barang, jumlah] — destructuring array di parameter, keluarga dekat dari destructuring object yang baru saja kita pelajari — lalu mencetak baris stok sekaligus menjumlahkan totalnya.

Referensi lanjutan untuk topik chapter ini:

Object sangat cocok untuk data yang tiap elemennya punya nama, tetapi banyak data di dunia nyata berbentuk daftar berurutan — daftar tugas, daftar harga, daftar baris database. Untuk itu JavaScript menyediakan array lengkap dengan higher-order function-nya, topik Chapter Array dan Higher-Order Function.