Bab 4: Tipe Data

10 menit baca

Setelah kita paham objek dasar, sekarang saatnya mendalami tipe data di JavaScript. Bab ini panjang tapi penting banget — karena di sinilah kamu belajar "senjata" yang bakal kamu pakai sehari-hari: angka, string, array, dan banyak lagi.


4.1 Method pada Primitif

Konsep Inti

Ini paradoks menarik di JavaScript: primitif bukan objek, tapi punya method.

Bayangin gini — primitif itu kayak kertas catatan kecil (ringan, cepat). Objek itu kayak binder tebal (berat, banyak fitur). Nah, JavaScript bikin "trik sulap": saat kamu panggil method di primitif, dia sementara bungkus primitif itu jadi objek, jalanin method-nya, terus buang bungkusnya.

javascript
const nama = "hello";
console.log(nama.toUpperCase()); // "HELLO"
// Di balik layar: String("hello") → panggil toUpperCase() → buang wrapper

7 Tipe Primitif

  1. string — teks
  2. number — angka
  3. bigint — angka super besar
  4. boolean — true/false
  5. symbol — identitas unik
  6. null — "kosong dengan sengaja"
  7. undefined — "belum diisi"
⚠️Jebakan!
javascript
// JANGAN pakai new String(), new Number(), dll
const angka = new Number(0);
if (angka) {
  console.log("Ini jalan!"); // JALAN! Karena objek selalu truthy
}

// Yang benar — pakai tanpa new untuk konversi:
const num = Number("123"); // 123 (primitif, bukan objek)

null dan undefined tidak punya method apapun. Kalau kamu coba null.toString() → error.

🎯Challenge
javascript
// Apa output kode ini? Jelaskan kenapa.
let str = "Hello";
str.test = 5;
console.log(str.test); // ???

4.2 Number (Angka)

Cara Menulis Angka

javascript
// Angka biasa
const sejuta = 1000000;

// Pakai underscore biar gampang dibaca (syntactic sugar)
const sejutaRapi = 1_000_000; // sama aja dengan 1000000

// Pakai notasi "e" (eksponen)
const seMilyar = 1e9;    // 1 × 10^9 = 1.000.000.000
const mikroDetik = 1e-6; // 1 × 10^-6 = 0.000001

Analogi: e itu kayak shortcut. 1e9 artinya "1 diikuti 9 nol". 1e-6 artinya "1 dibagi 10 sebanyak 6 kali".

Sistem Bilangan (Hex, Binary, Octal)

javascript
console.log(0xff);        // 255 (hexadecimal — sering buat warna)
console.log(0b11111111);  // 255 (binary)
console.log(0o377);       // 255 (octal)

// Konversi angka ke string dengan basis tertentu
const num = 255;
console.log(num.toString(16)); // "ff"
console.log(num.toString(2));  // "11111111"

Pembulatan

MethodFungsiContoh (3.6)Contoh (-1.2)
Math.floorBulatkan ke bawah3-2
Math.ceilBulatkan ke atas4-1
Math.roundBulatkan terdekat4-1
Math.truncPotong desimal3-1
javascript
// Bulatkan ke 2 desimal
const harga = 19.567;
console.log(harga.toFixed(2)); // "19.57" (hasilnya STRING!)
console.log(+harga.toFixed(2)); // 19.57 (konversi ke number pakai +)

⚠️ Jebakan: Ketidaktelitian Floating Point

javascript
console.log(0.1 + 0.2); // 0.30000000000000004 — BUKAN 0.3!
console.log(0.1 + 0.2 === 0.3); // false 😱

Kenapa? Angka disimpan dalam format biner 64-bit (IEEE-754). Pecahan seperti 0.1 dan 0.2 itu tak terhingga dalam biner — kayak 1/3 = 0.3333... di desimal. Jadi ada sedikit "sisa" yang menumpuk.

Solusi:

javascript
// Cara 1: toFixed
const total = +(0.1 + 0.2).toFixed(2); // 0.3

// Cara 2: Kalikan dulu, bagi kemudian
const total2 = (0.1 * 10 + 0.2 * 10) / 10; // 0.3

Pengecekan: isNaN dan isFinite

javascript
console.log(isNaN("bukan angka")); // true — dikonversi jadi NaN
console.log(isNaN(123));           // false

console.log(NaN === NaN); // false! NaN tidak sama dengan apapun, termasuk dirinya sendiri

console.log(isFinite("15"));       // true (string "15" → angka 15)
console.log(isFinite("abc"));      // false (jadi NaN)
console.log(isFinite(Infinity));   // false

Kapan pakai isFinite? Untuk validasi input user — cek apakah yang diketik benar-benar angka valid.

parseInt dan parseFloat

javascript
// Baca angka dari string yang ada teks-nya
console.log(parseInt("100px"));    // 100
console.log(parseFloat("12.5em")); // 12.5
console.log(parseInt("12.3"));     // 12 (hanya integer)
console.log(parseInt("a123"));     // NaN (karakter pertama bukan angka)

// parseInt dengan basis (radix)
console.log(parseInt("ff", 16));   // 255
console.log(parseInt("11", 2));    // 3 (binary)

Fungsi Math Lainnya

javascript
console.log(Math.random());       // Angka acak 0 sampai 1 (tidak termasuk 1)
console.log(Math.max(3, 5, -10)); // 5
console.log(Math.min(3, 5, -10)); // -10
console.log(Math.pow(2, 10));     // 1024 (2 pangkat 10)
console.log(Math.sqrt(9));        // 3
console.log(Math.abs(-5));        // 5
🎯Challenge
javascript
// Buat fungsi yang menghasilkan angka bulat acak antara min dan max (inklusif)
// Contoh: randomInteger(1, 5) bisa menghasilkan 1, 2, 3, 4, atau 5
function randomInteger(min, max) {
  // kode kamu di sini
}

4.3 String (Teks)

Tiga Jenis Kutipan

javascript
const single = 'kutip satu';
const double = "kutip dua";
const backtick = `backtick — bisa embed ${1 + 2} dan
multi-baris`;

Aturan praktis: Pakai backtick (`) kalau butuh interpolasi atau multi-baris. Sisanya terserah — yang penting konsisten.

Karakter Spesial

KarakterFungsi
\nBaris baru
\tTab
\\Backslash literal
\'Kutip satu di dalam string kutip satu
javascript
console.log("Baris 1\nBaris 2");
// Output:
// Baris 1
// Baris 2

Panjang String & Akses Karakter

javascript
const str = "Hello";
console.log(str.length); // 5 (property, BUKAN function — tanpa ())

// Akses karakter
console.log(str[0]);     // "H"
console.log(str.at(-1)); // "o" (dari belakang — fitur modern)
console.log(str[-1]);    // undefined (bracket biasa tak support negatif)

⚠️ Jebakan: String Itu Immutable

javascript
let str = "Hello";
str[0] = "h"; // TIDAK BISA! Tidak error tapi tidak berubah
console.log(str); // tetap "Hello"

// Solusi: buat string baru
str = "h" + str.slice(1); // "hello"

Mengubah Huruf Besar/Kecil

javascript
console.log("Interface".toUpperCase()); // "INTERFACE"
console.log("Interface".toLowerCase()); // "interface"

Mencari Substring

javascript
const str = "Widget with id";

// includes — cek ada atau tidak (true/false)
console.log(str.includes("Widget")); // true
console.log(str.includes("widget")); // false (case-sensitive!)

// startsWith / endsWith
console.log(str.startsWith("Wid")); // true
console.log(str.endsWith("id"));    // true

// indexOf — cari posisi (return -1 kalau tidak ketemu)
console.log(str.indexOf("id"));     // 1 (posisi pertama ditemukan)
console.log(str.indexOf("id", 2));  // 12 (cari mulai posisi 2)

Mengambil Potongan String (Slice)

javascript
const str = "stringify";

// slice(start, end) — end tidak termasuk
console.log(str.slice(0, 5));  // "strin"
console.log(str.slice(2));     // "ringify" (sampai akhir)
console.log(str.slice(-4, -1)); // "gif" (dari belakang)

Tips: Cukup ingat slice saja. Ada juga substring dan substr, tapi slice paling fleksibel dan paling sering dipakai.

Perbandingan String

javascript
// Huruf kecil > huruf besar (berdasarkan kode Unicode)
console.log("a" > "Z"); // true (kode 'a' = 97, 'Z' = 90)

// Untuk perbandingan yang benar secara bahasa:
console.log("Österreich".localeCompare("Zealand")); // -1 (Ö sebelum Z)
🎯Challenge
javascript
// Buat fungsi truncate(str, maxlength)
// Jika str lebih panjang dari maxlength, potong dan tambahkan "…" di akhir
// Total panjang hasil = maxlength
// Contoh: truncate("Halo semua, apa kabar?", 10) → "Halo semu…"
function truncate(str, maxlength) {
  // kode kamu di sini
}

4.4 Array (Daftar Berurutan)

Kenapa Butuh Array?

Objek menyimpan data dengan "nama" (key). Tapi kadang kita butuh data berurutan — daftar belanjaan, antrian pesan, koleksi user. Di sinilah array berperan.

Analogi: Array itu kayak rak buku bernomor. Buku pertama di slot 0, kedua di slot 1, dst.

Membuat Array

javascript
// Cara yang direkomendasikan
const buah = ["Apel", "Jeruk", "Mangga"];

// Akses elemen (mulai dari 0!)
console.log(buah[0]); // "Apel"
console.log(buah[2]); // "Mangga"

// Ganti elemen
buah[1] = "Pisang"; // ["Apel", "Pisang", "Mangga"]

// Cek panjang
console.log(buah.length); // 3

// Akses dari belakang
console.log(buah.at(-1)); // "Mangga"

Menambah & Menghapus Elemen

javascript
const buah = ["Apel", "Jeruk"];

// === BELAKANG (CEPAT) ===
buah.push("Mangga");    // Tambah di belakang → ["Apel", "Jeruk", "Mangga"]
buah.pop();             // Hapus dari belakang → ["Apel", "Jeruk"], return "Mangga"

// === DEPAN (LAMBAT) ===
buah.unshift("Pisang"); // Tambah di depan → ["Pisang", "Apel", "Jeruk"]
buah.shift();           // Hapus dari depan → ["Apel", "Jeruk"], return "Pisang"

Kenapa depan lambat? Karena semua elemen harus digeser (re-index). Kalau array punya 1000 elemen, shift() harus geser 999 elemen. pop() cuma hapus 1 elemen di ujung — tidak perlu geser apapun.

Looping Array

javascript
const buah = ["Apel", "Jeruk", "Mangga"];

// Cara 1: for klasik (akses index)
for (let i = 0; i < buah.length; i++) {
  console.log(buah[i]);
}

// Cara 2: for...of (lebih ringkas, tanpa index)
for (const item of buah) {
  console.log(item);
}

// ❌ JANGAN pakai for...in untuk array!
// for...in itu untuk objek, bukan array — bisa iterasi property non-numerik
⚠️Jebakan!
javascript
// 1. Array itu objek — di-copy by reference!
const a = [1, 2, 3];
const b = a; // b BUKAN salinan, tapi referensi ke array yang SAMA
b.push(4);
console.log(a); // [1, 2, 3, 4] — ikut berubah!

// 2. Jangan bandingkan array dengan ==
console.log([] == []);   // false (dua objek berbeda)
console.log([0] == [0]); // false

// 3. new Array(number) bikin array KOSONG dengan panjang tertentu
const arr = new Array(5);
console.log(arr[0]); // undefined
console.log(arr.length); // 5

Array Multi-Dimensi

javascript
const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

console.log(matrix[1][2]); // 6 (baris ke-1, kolom ke-2)
🎯Challenge
javascript
// Buat array styles dengan "Jazz" dan "Blues"
// 1. Tambahkan "Rock-n-Roll" di akhir
// 2. Ganti nilai di tengah dengan "Classics"
// 3. Hapus elemen pertama dan tampilkan
// 4. Tambahkan "Rap" dan "Reggae" di awal
// Hasil akhir: ["Rap", "Reggae", "Classics", "Rock-n-Roll"]

4.5 Method Array

Ini bagian yang paling sering dipakai dalam coding sehari-hari. Kuasai ini dan kamu bisa manipulasi data apapun.

splice — Pisau Swiss Army

splice bisa menambah, menghapus, dan mengganti elemen sekaligus.

javascript
// arr.splice(index, deleteCount, ...items)
const arr = ["Aku", "belajar", "JavaScript"];

// Hapus 1 elemen mulai index 1
arr.splice(1, 1); // ["Aku", "JavaScript"]

// Hapus 2 elemen dan ganti dengan yang baru
const arr2 = ["Aku", "belajar", "JavaScript", "sekarang"];
arr2.splice(0, 2, "Kita", "menguasai");
// ["Kita", "menguasai", "JavaScript", "sekarang"]

// Sisipkan tanpa menghapus (deleteCount = 0)
const arr3 = [1, 2, 5];
arr3.splice(2, 0, 3, 4); // [1, 2, 3, 4, 5]

// Index negatif = dari belakang
const arr4 = [1, 2, 3, 4, 5];
arr4.splice(-2, 2); // [1, 2, 3] — hapus 2 elemen dari index -2

slice — Potong Tanpa Mengubah Asli

javascript
// arr.slice(start, end) — end tidak termasuk
const arr = ["H", "e", "l", "l", "o"];

console.log(arr.slice(1, 3)); // ["e", "l"]
console.log(arr.slice(-2));   // ["l", "o"]
console.log(arr.slice());     // ["H", "e", "l", "l", "o"] — salinan penuh!

Perbedaan splice vs slice:

  • splicemengubah array asli (mutasi)
  • slicetidak mengubah array asli (return array baru)

concat — Gabungkan Array

javascript
const arr1 = [1, 2];
const arr2 = [3, 4];

console.log(arr1.concat(arr2));       // [1, 2, 3, 4]
console.log(arr1.concat(arr2, [5]));  // [1, 2, 3, 4, 5]
console.log(arr1.concat(arr2, 99));   // [1, 2, 3, 4, 99]

forEach — Jalankan Fungsi untuk Setiap Elemen

javascript
const buah = ["Apel", "Jeruk", "Mangga"];

buah.forEach((item, index) => {
  console.log(`${index}: ${item}`);
});
// 0: Apel
// 1: Jeruk
// 2: Mangga

Pencarian dalam Array

javascript
const arr = [1, 0, false, "halo", NaN];

// indexOf / lastIndexOf — cari posisi (pakai ===)
console.log(arr.indexOf(0));     // 1
console.log(arr.indexOf(null));  // -1 (tidak ada)

// includes — cek keberadaan (true/false)
console.log(arr.includes(false)); // true
console.log(arr.includes(NaN));   // true (includes bisa deteksi NaN!)

// find — cari elemen pertama yang cocok
const users = [
  { id: 1, nama: "Andi" },
  { id: 2, nama: "Budi" },
  { id: 3, nama: "Cici" }
];

const user = users.find(item => item.id === 2);
console.log(user.nama); // "Budi"

// findIndex — sama tapi return index
const index = users.findIndex(item => item.id === 2);
console.log(index); // 1

// filter — cari SEMUA yang cocok (return array baru)
const hasil = users.filter(item => item.id > 1);
console.log(hasil); // [{id:2, nama:"Budi"}, {id:3, nama:"Cici"}]

Transformasi Array

javascript
// map — ubah setiap elemen (return array baru)
const angka = [1, 2, 3, 4];
const kuadrat = angka.map(n => n * n);
console.log(kuadrat); // [1, 4, 9, 16]

// sort — urutkan (MENGUBAH array asli!)
const buah = ["Pisang", "Apel", "Mangga"];
buah.sort();
console.log(buah); // ["Apel", "Mangga", "Pisang"]

// ⚠️ sort angka butuh fungsi pembanding!
const nums = [1, 15, 2, 30];
nums.sort(); // [1, 15, 2, 30] — SALAH! (diurutkan sebagai string)
nums.sort((a, b) => a - b); // [1, 2, 15, 30] — BENAR!

// reverse — balik urutan (MENGUBAH array asli!)
const arr = [1, 2, 3];
arr.reverse();
console.log(arr); // [3, 2, 1]

// reduce — "lipat" array jadi satu nilai
const angka2 = [1, 2, 3, 4, 5];
const total = angka2.reduce((akumulator, item) => akumulator + item, 0);
console.log(total); // 15

// Cara kerja reduce:
// Langkah 1: akumulator=0, item=1 → 0+1=1
// Langkah 2: akumulator=1, item=2 → 1+2=3
// Langkah 3: akumulator=3, item=3 → 3+3=6
// Langkah 4: akumulator=6, item=4 → 6+4=10
// Langkah 5: akumulator=10, item=5 → 10+5=15

split dan join — Konversi String ↔ Array

javascript
// split — pecah string jadi array
const nama = "Andi, Budi, Cici";
const arr = nama.split(", ");
console.log(arr); // ["Andi", "Budi", "Cici"]

// join — gabung array jadi string
const hasil = arr.join(" & ");
console.log(hasil); // "Andi & Budi & Cici"

Array.isArray — Cek Apakah Array

javascript
console.log(Array.isArray([1, 2]));  // true
console.log(Array.isArray("hello")); // false
console.log(typeof [1, 2]);         // "object" — typeof tidak bisa bedakan!
🎯Challenge
javascript
// Diberikan array nama:
const names = ["Andi", "Budi", "Cici", "Dedi", "Eka"];

// 1. Filter nama yang panjangnya > 3 huruf
// 2. Ubah semua jadi huruf besar
// 3. Gabungkan dengan " - "
// Hasil: "ANDI - BUDI - CICI - DEDI"

4.6 Iterables (Objek yang Bisa Di-loop)

Konsep

Iterable = objek yang bisa dipakai di for...of. Array dan string adalah iterable bawaan.

javascript
// String itu iterable
for (const char of "Halo") {
  console.log(char); // H, a, l, o
}

// Array itu iterable
for (const item of [1, 2, 3]) {
  console.log(item); // 1, 2, 3
}

Array.from — Ubah Iterable/Array-like Jadi Array Asli

javascript
// String → Array
const arr = Array.from("Halo");
console.log(arr); // ["H", "a", "l", "o"]

// Dengan fungsi transformasi
const nums = Array.from("12345", num => +num);
console.log(nums); // [1, 2, 3, 4, 5]

// Bikin array dengan range
const range = Array.from({ length: 5 }, (_, i) => i + 1);
console.log(range); // [1, 2, 3, 4, 5]
⚠️Jebakan!

Iterable ≠ Array. Iterable hanya berarti "bisa di-loop". Belum tentu punya .push(), .map(), dll. Kalau butuh method array, konversi dulu pakai Array.from().

🎯Challenge
javascript
// Buat array berisi angka 10, 20, 30, ..., 100 menggunakan Array.from
// (tanpa loop manual)

4.7 Map dan Set

Map — Objek dengan Key Apapun

Objek biasa ({}) hanya bisa pakai string/symbol sebagai key. Map bisa pakai tipe apapun sebagai key — angka, objek, bahkan fungsi!

javascript
const map = new Map();

// Set key-value
map.set("nama", "Andi");
map.set(1, "angka satu");
map.set(true, "boolean true");

// Get value
console.log(map.get("nama")); // "Andi"
console.log(map.get(1));      // "angka satu"

// Cek keberadaan & ukuran
console.log(map.has("nama")); // true
console.log(map.size);        // 3

// Hapus
map.delete(1);

Kapan pakai Map vs Object?

  • Key bukan string → Map
  • Perlu tahu jumlah elemen → Map (.size)
  • Sering tambah/hapus key → Map (lebih optimal)
  • Butuh JSON serialization → Object (Map tidak bisa langsung JSON.stringify)

Iterasi Map

javascript
const menu = new Map([
  ["nasi goreng", 25000],
  ["mie ayam", 20000],
  ["es teh", 5000]
]);

// Iterasi key
for (const item of menu.keys()) {
  console.log(item); // "nasi goreng", "mie ayam", "es teh"
}

// Iterasi value
for (const harga of menu.values()) {
  console.log(harga); // 25000, 20000, 5000
}

// Iterasi key-value
for (const [item, harga] of menu) {
  console.log(`${item}: Rp${harga}`);
}

Set — Koleksi Nilai Unik

Set itu kayak array, tapi tidak boleh ada duplikat.

javascript
const set = new Set();

set.add(1);
set.add(2);
set.add(2); // diabaikan — sudah ada!
set.add("halo");

console.log(set.size); // 3
console.log(set.has(2)); // true

// Use case paling umum: hapus duplikat dari array
const angka = [1, 2, 2, 3, 3, 3, 4];
const unik = [...new Set(angka)];
console.log(unik); // [1, 2, 3, 4]
🎯Challenge
javascript
// Diberikan array dengan duplikat:
const pesan = ["Halo", "Dunia", "Halo", "JavaScript", "Dunia", "Halo"];

// Gunakan Set untuk menghitung berapa banyak pesan UNIK
// Output yang diharapkan: 3

4.8 WeakMap dan WeakSet

Masalah yang Dipecahkan

Di Map/Set biasa, kalau kamu simpan objek sebagai key, objek itu tidak akan di-garbage collect selama Map/Set masih ada — meskipun tidak ada referensi lain ke objek itu. Ini bisa bikin memory leak.

WeakMap dan WeakSet memecahkan ini: mereka tidak mencegah garbage collection.

javascript
let user = { nama: "Andi" };

const weakMap = new WeakMap();
weakMap.set(user, "data rahasia");

user = null; // objek { nama: "Andi" } sekarang bisa di-garbage collect!
// Entry di weakMap juga otomatis hilang

Batasan WeakMap/WeakSet

  • Key harus objek (bukan primitif)
  • Tidak bisa di-iterasi (tidak ada for...of, .keys(), .size)
  • Hanya punya: get, set, has, delete (WeakMap) / add, has, delete (WeakSet)

Kapan Pakai?

  1. Caching — simpan hasil komputasi yang terkait objek, otomatis hilang saat objek dihapus
  2. Data tambahan — "tempelkan" data ke objek tanpa modifikasi objek itu sendiri
  3. Tracking — tandai objek yang sudah diproses
javascript
// Contoh: caching
const cache = new WeakMap();

function hitungBerat(obj) {
  if (cache.has(obj)) {
    return cache.get(obj); // ambil dari cache
  }
  const hasil = /* komputasi berat */ obj.data.length;
  cache.set(obj, hasil);
  return hasil;
}
🎯Challenge
javascript
// Jelaskan dengan kata-katamu sendiri:
// Kenapa WeakMap tidak punya property .size dan tidak bisa di-loop?

4.9 Object.keys, values, entries

Iterasi Objek Biasa

Objek biasa tidak punya .map(), .filter(), dll. Tapi kita bisa "konversi" dulu ke array:

javascript
const harga = {
  nasiGoreng: 25000,
  mieAyam: 20000,
  esTeh: 5000
};

// Ambil semua key
console.log(Object.keys(harga));   // ["nasiGoreng", "mieAyam", "esTeh"]

// Ambil semua value
console.log(Object.values(harga)); // [25000, 20000, 5000]

// Ambil pasangan [key, value]
console.log(Object.entries(harga)); // [["nasiGoreng",25000], ["mieAyam",20000], ["esTeh",5000]]

Trik: Pakai Method Array di Objek

javascript
const harga = {
  nasiGoreng: 25000,
  mieAyam: 20000,
  esTeh: 5000
};

// Naikkan semua harga 10%
const hargaBaru = Object.fromEntries(
  Object.entries(harga).map(([key, val]) => [key, val * 1.1])
);
console.log(hargaBaru);
// { nasiGoreng: 27500, mieAyam: 22000, esTeh: 5500 }

Pola umum: Object.entries() → transformasi dengan method array → Object.fromEntries()

🎯Challenge
javascript
// Diberikan objek gaji:
const gaji = { andi: 5000000, budi: 8000000, cici: 6000000 };

// Buat objek baru yang hanya berisi orang dengan gaji > 5.500.000
// Hasil: { budi: 8000000, cici: 6000000 }

4.10 Destructuring Assignment

Konsep

Destructuring = "membongkar" array/objek ke variabel-variabel terpisah. Ini bikin kode lebih ringkas dan mudah dibaca.

Analogi: Kayak buka kado — kamu "keluarkan" isinya satu per satu ke tempat masing-masing.

Destructuring Array

javascript
const buah = ["Apel", "Jeruk", "Mangga"];

// Tanpa destructuring
const pertama = buah[0];
const kedua = buah[1];

// Dengan destructuring ✨
const [a, b, c] = buah;
console.log(a); // "Apel"
console.log(b); // "Jeruk"
console.log(c); // "Mangga"

// Skip elemen dengan koma
const [, , ketiga] = buah;
console.log(ketiga); // "Mangga"

// Rest pattern — ambil sisanya
const [first, ...rest] = buah;
console.log(first); // "Apel"
console.log(rest);  // ["Jeruk", "Mangga"]

// Default value
const [x = "kosong", y = "kosong"] = ["ada"];
console.log(x); // "ada"
console.log(y); // "kosong" (pakai default)

// Swap variabel tanpa temp!
let kiri = 1, kanan = 2;
[kiri, kanan] = [kanan, kiri];
console.log(kiri, kanan); // 2, 1

Destructuring Objek

javascript
const user = {
  nama: "Andi",
  umur: 25,
  kota: "Jakarta"
};

// Tanpa destructuring
const nama = user.nama;
const umur = user.umur;

// Dengan destructuring ✨
const { nama, umur, kota } = user;
console.log(nama); // "Andi"

// Rename variabel
const { nama: namaUser, umur: usia } = user;
console.log(namaUser); // "Andi"
console.log(usia);     // 25

// Default value
const { nama, email = "tidak ada" } = user;
console.log(email); // "tidak ada"

// Rest pattern
const { nama, ...sisanya } = user;
console.log(sisanya); // { umur: 25, kota: "Jakarta" }

Destructuring di Parameter Fungsi

javascript
// Tanpa destructuring
function tampilUser(user) {
  console.log(`${user.nama}, ${user.umur} tahun`);
}

// Dengan destructuring ✨
function tampilUser({ nama, umur }) {
  console.log(`${nama}, ${umur} tahun`);
}

tampilUser({ nama: "Andi", umur: 25 }); // "Andi, 25 tahun"
⚠️Jebakan!
javascript
// Destructuring objek TANPA let/const butuh kurung
let nama, umur;
({ nama, umur } = { nama: "Andi", umur: 25 }); // Perlu ( ) di luar!
// Tanpa ( ), JavaScript mengira { } adalah blok kode
🎯Challenge
javascript
// Diberikan objek:
const config = {
  host: "localhost",
  port: 3000,
  database: {
    name: "mydb",
    user: "admin"
  }
};

// Gunakan destructuring untuk mengambil:
// - host (rename jadi serverHost)
// - port (dengan default 8080)
// - database.name (rename jadi dbName)

4.11 Date dan Time

Membuat Objek Date

javascript
// Waktu sekarang
const sekarang = new Date();
console.log(sekarang); // Tue May 05 2026 ...

// Dari string
const tanggal = new Date("2026-01-15");

// Dari komponen (bulan mulai dari 0!)
const tahunBaru = new Date(2026, 0, 1); // 1 Januari 2026
//                         tahun, bulan(0-11), tanggal, jam, menit, detik, ms

// Dari timestamp (milidetik sejak 1 Jan 1970)
const d = new Date(0); // 1 Jan 1970 UTC

⚠️ Jebakan: Bulan Mulai dari 0!

javascript
// Januari = 0, Februari = 1, ..., Desember = 11
const maret = new Date(2026, 2, 1); // 1 Maret 2026 (BUKAN Februari!)

Mengambil Komponen

javascript
const now = new Date();

console.log(now.getFullYear());  // 2026 (JANGAN pakai getYear()!)
console.log(now.getMonth());     // 0-11
console.log(now.getDate());      // 1-31
console.log(now.getDay());       // 0-6 (0 = Minggu)
console.log(now.getHours());     // 0-23
console.log(now.getMinutes());   // 0-59
console.log(now.getSeconds());   // 0-59
console.log(now.getTime());      // timestamp dalam milidetik

Mengatur Komponen

javascript
const d = new Date();
d.setFullYear(2030);
d.setMonth(11);  // Desember
d.setDate(25);   // Tanggal 25
// Sekarang d = 25 Desember 2030

Menghitung Selisih Waktu

javascript
const mulai = new Date();

// ... proses yang mau diukur ...
for (let i = 0; i < 1000000; i++) {} // simulasi kerja

const selesai = new Date();
console.log(`Waktu: ${selesai - mulai} ms`); // Date bisa dikurangi!
🎯Challenge
javascript
// Buat fungsi yang menghitung umur seseorang berdasarkan tanggal lahir
// Input: string tanggal lahir "YYYY-MM-DD"
// Output: umur dalam tahun (bilangan bulat)
function hitungUmur(tanggalLahir) {
  // kode kamu di sini
}

// Test: hitungUmur("2000-05-15") → (tergantung tanggal hari ini)

4.12 JSON (JavaScript Object Notation)

Kenapa Butuh JSON?

Saat kamu mau kirim data ke server atau simpan ke file, kamu tidak bisa kirim objek JavaScript langsung. Kamu perlu mengubahnya jadi teks (string). JSON adalah format standar untuk ini.

Analogi: JSON itu kayak "bahasa universal" untuk data. Semua bahasa pemrograman bisa baca JSON.

JSON.stringify — Objek → String

javascript
const user = {
  nama: "Andi",
  umur: 25,
  hobi: ["coding", "gaming"],
  aktif: true
};

const json = JSON.stringify(user);
console.log(json);
// '{"nama":"Andi","umur":25,"hobi":["coding","gaming"],"aktif":true}'
console.log(typeof json); // "string"

JSON.parse — String → Objek

javascript
const json = '{"nama":"Andi","umur":25}';
const obj = JSON.parse(json);
console.log(obj.nama); // "Andi"
console.log(obj.umur); // 25

Yang Didukung JSON

✅ String, Number, Boolean, null, Array, Object

❌ Function, undefined, Symbol, Date (jadi string), RegExp

javascript
const data = {
  nama: "Andi",
  sayHi: function() {},  // ❌ diabaikan
  umur: undefined,       // ❌ diabaikan
  tanggal: new Date()    // ⚠️ jadi string "2026-05-05T..."
};

console.log(JSON.stringify(data));
// '{"nama":"Andi","tanggal":"2026-05-05T..."}'

Formatting JSON (Pretty Print)

javascript
const user = { nama: "Andi", umur: 25, kota: "Jakarta" };

// Parameter ketiga = jumlah spasi indentasi
console.log(JSON.stringify(user, null, 2));
// {
//   "nama": "Andi",
//   "umur": 25,
//   "kota": "Jakarta"
// }

toJSON — Custom Serialization

javascript
const meeting = {
  judul: "Standup",
  tanggal: new Date(),
  toJSON() {
    return {
      judul: this.judul,
      tanggal: this.tanggal.toLocaleDateString("id-ID")
    };
  }
};

console.log(JSON.stringify(meeting));
// '{"judul":"Standup","tanggal":"5/5/2026"}'
⚠️Jebakan!
javascript
// JSON.parse bisa error kalau string-nya tidak valid!
try {
  const data = JSON.parse("bukan json");
} catch (e) {
  console.log("Error:", e.message); // Unexpected token...
}

// Deep copy objek (trik sederhana)
const original = { a: 1, b: { c: 2 } };
const copy = JSON.parse(JSON.stringify(original));
copy.b.c = 99;
console.log(original.b.c); // 2 (tidak ikut berubah!)
// ⚠️ Tapi ini tidak bekerja untuk function, undefined, Date, dll
🎯Challenge
javascript
// Diberikan objek:
const data = {
  nama: "Andi",
  password: "rahasia123",
  email: "andi@mail.com",
  umur: 25
};

// Gunakan JSON.stringify dengan parameter "replacer" (parameter kedua)
// untuk menghasilkan JSON yang TIDAK menyertakan field "password"
// Hint: replacer bisa berupa array nama field yang mau disertakan

Ringkasan Bab 4

TopikPoin Kunci
Method PrimitifPrimitif punya method via "wrapper" sementara
NumbertoFixed, pembulatan, 0.1+0.2 problem, parseInt/parseFloat
StringImmutable, slice, includes, indexOf, template literal
ArrayOrdered collection, push/pop cepat, shift/unshift lambat
Array Methodsmap, filter, reduce, find, sort, splice
IterablesObjek yang bisa di-for...of, Array.from
Map & SetMap = key apapun, Set = nilai unik
WeakMap/WeakSetTidak cegah garbage collection
Object.keys/values/entriesKonversi objek → array untuk transformasi
DestructuringBongkar array/objek ke variabel
DateBulan dari 0, getTime() untuk timestamp
JSONstringify & parse, format pertukaran data universal

Selamat! 🎉 Bab ini adalah salah satu yang terpanjang tapi juga terpenting. Kalau kamu sudah paham array methods (map, filter, reduce) dan destructuring, kamu sudah punya "senjata utama" untuk coding JavaScript sehari-hari.

Next: Bab 5 — Fungsi Lanjutan (Closure, Rekursi, setTimeout, dll.)

Sudah paham materi ini?

Tandai sebagai selesai untuk melacak progress-mu.