⚡ JavaScript

Bahasa pemrograman web. Bikin halaman jadi interaktif dan hidup.

📌 Baca ini dulu sebelum lanjut!

🧱 Fundamental JavaScript

Sebelum masuk detail syntax satu-satu, pahami dulu konsep-konsep inti ini. Cuma butuh beberapa menit, tapi bakal bikin materi selanjutnya jauh lebih gampang dicerna.

📌 Fundamental JavaScript udah kamu baca.

Pengenalan JavaScript

JavaScript (JS) adalah bahasa pemrograman yang berjalan di browser. Lewat JS, kita bisa memanipulasi HTML/CSS secara dinamis, merespons aksi pengguna seperti klik, mengambil data dari server, menyimpan data di perangkat, dan masih banyak lagi.

💡 JS bisa ditulis langsung di file HTML pakai tag <script>, atau di file terpisah .js yang di-link ke HTML.
javascript
// Cara 1: langsung di HTML
<script>
  console.log("Halo dari JS!");
</script>

// Cara 2: file terpisah
<script src="script.js"></script>
✅ Best Practice: Letakkan tag <script> sebelum penutup </body> (atau pakai atribut defer kalau diletakkan di <head>) supaya HTML selesai dimuat dulu sebelum JS dijalankan.

Variabel

Variabel adalah "wadah" untuk menyimpan data supaya bisa dipakai dan diubah di sepanjang program. Ada tiga cara deklarasi:

  • let — nilainya bisa diubah, paling sering dipakai untuk data yang berubah-ubah
  • const — nilainya tetap setelah didefinisikan, jadi pilihan default yang direkomendasikan
  • var — cara lama dengan beberapa perilaku membingungkan, sebaiknya dihindari di kode baru
javascript
let nama = "Diki";         // bisa diubah
nama = "Budi";             // ✅ valid

const umur = 20;           // tidak bisa diubah
// umur = 21;              // ❌ error!

let nilai;                 // deklarasi tanpa isi = undefined
console.log(nama, umur);  // Budi 20
✅ Best Practice: Pakai const sebagai default, dan ganti ke let hanya kalau memang nilainya perlu berubah nanti. Ini bikin kode lebih aman dari perubahan nilai yang tidak disengaja.

Tipe Data

JavaScript punya beberapa tipe data dasar yang perlu diketahui sebelum lanjut ke materi lain:

javascript
// String — teks
let nama = "Siti";
let sapa = `Halo, ${nama}!`;  // template literal

// Number — angka
let nilai = 95;
let harga = 29.99;

// Boolean — true/false
let sudahLogin = true;
let isAdmin    = false;

// Array — kumpulan data
let buah = ["apel", "mangga", "jeruk"];
console.log(buah[0]);  // "apel"

// Object — pasangan key-value
let user = {
  nama: "Diki",
  umur: 20,
  aktif: true
};
console.log(user.nama);  // "Diki"
💡 Cek tipe data sebuah nilai pakai operator typeof, contoh: typeof nilai menghasilkan "number".

Kondisi

Kondisi dipakai untuk mengambil keputusan dalam kode berdasarkan nilai tertentu — mirip seperti percabangan jalan, program akan memilih jalur kode mana yang dijalankan.

javascript
let nilai = 80;

// if / else if / else
if (nilai >= 90) {
  console.log("A - Sangat Baik");
} else if (nilai >= 75) {
  console.log("B - Baik");
} else if (nilai >= 60) {
  console.log("C - Cukup");
} else {
  console.log("D - Perlu Belajar Lagi");
}

// Ternary — kondisi singkat untuk kasus sederhana
let status = nilai >= 75 ? "Lulus" : "Tidak Lulus";
console.log(status);  // "Lulus"
✅ Best Practice: Pakai ternary hanya untuk kondisi sederhana satu baris. Kalau logikanya sudah kompleks (banyak else if), if/else biasa lebih mudah dibaca daripada ternary bersarang.

Perulangan

Loop dipakai untuk menjalankan kode berulang kali tanpa harus menulis ulang baris yang sama.

javascript
// for loop
for (let i = 1; i <= 5; i++) {
  console.log("Nomor " + i);
}

// while loop
let angka = 0;
while (angka < 3) {
  console.log("angka:", angka);
  angka++;
}

// forEach — loop khusus array
const buah = ["apel", "mangga", "jeruk"];
buah.forEach((item, index) => {
  console.log(index + ": " + item);
});
✅ Best Practice: Untuk loop di atas array, lebih disarankan pakai forEach atau method array modern lain (lihat section Array Methods) daripada for biasa — kodenya lebih singkat dan jelas maksudnya.

Fungsi

Fungsi adalah blok kode yang bisa dipanggil berulang kali. Fungsi bikin kode jadi rapi, terorganisir, dan reusable (bisa dipakai ulang).

javascript
// Function declaration
function sapa(nama) {
  return `Halo, ${nama}!`;
}
console.log(sapa("Diki"));  // "Halo, Diki!"

// Arrow function (cara modern)
const tambah = (a, b) => a + b;
console.log(tambah(3, 7));  // 10

// Default parameter
function kali(a, b = 2) {
  return a * b;
}
console.log(kali(5));    // 10
console.log(kali(5, 3)); // 15

DOM Manipulation

DOM (Document Object Model) adalah representasi struktur HTML dalam bentuk objek yang bisa diakses dan diubah lewat JavaScript. Lewat DOM, kita bisa mengubah konten, style, atau struktur halaman secara dinamis tanpa reload halaman.

javascript
// Ambil elemen
const judul  = document.getElementById("judul");
const tombol = document.querySelector(".btn");
const semua  = document.querySelectorAll("p");

// Ubah konten
judul.textContent = "Judul Baru";
judul.innerHTML   = "Judul <span>Berwarna</span>";

// Ubah style
judul.style.color      = "blue";
judul.style.fontSize   = "2rem";
judul.style.fontWeight = "bold";

// Tambah / hapus class
judul.classList.add("aktif");
judul.classList.remove("aktif");
judul.classList.toggle("dark");
✅ Best Practice: Lebih baik pakai textContent daripada innerHTML kalau hanya menampilkan teks biasa — innerHTML bisa membuka celah keamanan (XSS) kalau isinya berasal dari input pengguna.

Event Listener

Event dipakai untuk membuat halaman merespons aksi pengguna seperti klik, input, hover, atau penekanan tombol keyboard.

javascript
const tombol = document.querySelector("#tombol");
const input  = document.querySelector("#nama");

// Klik
tombol.addEventListener("click", () => {
  alert("Tombol diklik!");
});

// Input berubah
input.addEventListener("input", (e) => {
  console.log("Nilai:", e.target.value);
});

// Mouse hover
tombol.addEventListener("mouseenter", () => {
  tombol.style.background = "blue";
});
tombol.addEventListener("mouseleave", () => {
  tombol.style.background = "";
});

// Tekan keyboard
document.addEventListener("keydown", (e) => {
  console.log("Tombol ditekan:", e.key);
});
✅ Best Practice: Pakai addEventListener, bukan atribut inline seperti onclick="..." di HTML — lebih mudah dikelola dan satu elemen bisa punya banyak listener untuk event yang sama.

Array Methods

Selain forEach, JavaScript punya beberapa method array modern yang sangat sering dipakai untuk mengolah data tanpa menulis loop manual. Empat yang paling penting: map, filter, find, dan reduce.

javascript
const siswa = [
  { nama: "Diki",  nilai: 90 },
  { nama: "Sari",  nilai: 65 },
  { nama: "Budi",  nilai: 78 },
  { nama: "Lala",  nilai: 55 },
];

// map() — ubah tiap item, hasilnya array BARU sepanjang array asli
const namaSaja = siswa.map(s => s.nama);
console.log(namaSaja); // ["Diki", "Sari", "Budi", "Lala"]

// filter() — ambil item yang lolos kondisi, hasilnya array baru (bisa lebih pendek)
const lulus = siswa.filter(s => s.nilai >= 75);
console.log(lulus); // [{nama:"Diki",...}, {nama:"Budi",...}]

// find() — ambil SATU item pertama yang cocok, atau undefined kalau tak ada
const siswaSari = siswa.find(s => s.nama === "Sari");
console.log(siswaSari); // {nama:"Sari", nilai:65}

// reduce() — "lipat" semua item jadi satu nilai akhir (total, rata-rata, dll)
const totalNilai = siswa.reduce((total, s) => total + s.nilai, 0);
console.log(totalNilai); // 288

// Method-method ini bisa disambung (chaining)
const rataRataLulus = siswa
  .filter(s => s.nilai >= 75)
  .reduce((t, s, _, arr) => t + s.nilai / arr.length, 0);
console.log(rataRataLulus.toFixed(1)); // 84.0
💡 map, filter, dan reduce tidak mengubah array aslinya (non-mutating) — selalu menghasilkan array atau nilai baru. Ini bikin kode lebih aman dan gampang ditebak alurnya.
✅ Best Practice: Pakai method array di atas dibanding for manual kalau tujuannya transformasi data (ubah/saring/gabung) — kodenya lebih deklaratif: langsung jelas "apa" yang ingin dicapai, bukan "bagaimana" loop-nya berjalan.

Modern JavaScript

JavaScript modern (ES6 ke atas) punya beberapa fitur sintaks yang bikin kode jauh lebih ringkas: destructuring, spread/rest operator, dan arrow function lanjutan.

javascript
/* === Destructuring === */
// Object destructuring — ambil property langsung jadi variabel
const user = { nama: "Diki", umur: 20, kota: "Jakarta" };
const { nama, kota } = user;
console.log(nama, kota); // "Diki" "Jakarta"

// Array destructuring — ambil item berdasarkan posisi
const warna = ["merah", "hijau", "biru"];
const [utama, , ketiga] = warna; // koma kosong = lewati index 1
console.log(utama, ketiga); // "merah" "biru"

/* === Spread operator (...) === */
// Menyebarkan isi array/object
const angka1 = [1, 2, 3];
const angka2 = [...angka1, 4, 5];
console.log(angka2); // [1, 2, 3, 4, 5]

const userBaru = { ...user, kota: "Bandung" }; // override properti kota
console.log(userBaru); // {nama:"Diki", umur:20, kota:"Bandung"}

/* === Rest operator (...) === */
// Mengumpulkan sisa argumen jadi array
function jumlahkan(...angka) {
  return angka.reduce((t, n) => t + n, 0);
}
console.log(jumlahkan(1, 2, 3, 4)); // 10

/* === Arrow function lanjutan === */
const kuadrat = n => n * n;              // 1 parameter, tanpa kurung
const sapa = () => "Halo!";              // tanpa parameter
const buatUser = (nama, umur) => ({ nama, umur }); // return object langsung
✅ Best Practice: Pakai destructuring saat mengambil beberapa properti dari object/array sekaligus, dan spread saat ingin menyalin atau menggabungkan array/object tanpa mengubah aslinya (immutability) — pola ini sangat umum dipakai di framework modern seperti React.

Async JavaScript

Sebagian kode butuh waktu untuk selesai (mis. ambil data dari server). JavaScript menangani ini secara asynchronous (tidak memblokir kode lain) lewat Promise dan sintaks async/await yang lebih modern dan mudah dibaca.

javascript
/* === Promise dasar === */
function tungguDetik(detik) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(`Selesai nunggu ${detik} detik`), detik * 1000);
  });
}

tungguDetik(2)
  .then(pesan => console.log(pesan))
  .catch(err => console.error(err));

/* === async/await (cara modern, lebih mudah dibaca) === */
async function mulai() {
  console.log("Mulai...");
  const pesan = await tungguDetik(1);
  console.log(pesan);
  console.log("Selesai!");
}
mulai();

/* === fetch — ambil data dari API === */
async function ambilData() {
  try {
    const res  = await fetch("https://jsonplaceholder.typicode.com/todos/1");
    const data = await res.json();
    console.log(data);
  } catch (err) {
    console.error("Gagal ambil data:", err.message);
  }
}
ambilData();
💡 await hanya boleh dipakai di dalam fungsi yang ditandai async. Selalu bungkus await dengan try/catch supaya error (mis. koneksi gagal) bisa ditangani dengan rapi.
✅ Best Practice: Pilih async/await dibanding .then() berantai untuk kode dengan banyak langkah berurutan — strukturnya jauh lebih mirip kode synchronous biasa sehingga lebih gampang dibaca dan di-debug.

LocalStorage

localStorage dipakai untuk menyimpan data langsung di browser pengguna, dan datanya tetap ada meskipun halaman di-refresh atau browser ditutup (beda dengan variabel JS biasa yang hilang saat halaman di-reload).

javascript
// Menyimpan data (cuma bisa string!)
localStorage.setItem("namaUser", "Diki");

// Mengambil data
const nama = localStorage.getItem("namaUser");
console.log(nama); // "Diki"

// Menghapus satu data
localStorage.removeItem("namaUser");

// Menghapus SEMUA data localStorage
localStorage.clear();

/* === Menyimpan object/array === */
// localStorage cuma terima string, jadi object/array harus diubah dulu
const todos = [
  { teks: "Belajar JS", selesai: false },
  { teks: "Push ke GitHub", selesai: true },
];

localStorage.setItem("todos", JSON.stringify(todos)); // object → string
const dataTodos = JSON.parse(localStorage.getItem("todos")); // string → object lagi
console.log(dataTodos);
💡 Kapasitas localStorage terbatas (sekitar 5–10MB tergantung browser) dan bukan tempat yang aman untuk data sensitif seperti password — siapa pun yang akses browser bisa membaca isinya lewat DevTools.
✅ Best Practice: Selalu bungkus JSON.parse() dengan try/catch di kode production — kalau data di localStorage rusak atau formatnya berubah, JSON.parse bisa melempar error dan menghentikan seluruh skrip.

🔮 Tebak Output

JavaScript suka ngasih kejutan — hoisting, type coercion, closure, referensi objek/array. Sebelum liat jawabannya, coba tebak dulu apa yang muncul di console dari tiap kode berikut.


⏱ Urutan Eksekusi

Ini konsep yang PALING sering bikin pemula JS bingung: kenapa setTimeout nggak langsung jalan? Kenapa Promise lebih "didahulukan" dari setTimeout? Tebak urutan console.log muncul dari tiap kode di bawah ini.


🐛 Betulin JS Rusak

6 kode di bawah ini punya bug klasik yang paling sering dibuat pemula (dan kadang juga yang udah lama ngoding!). Edit langsung di kotak abu-abu, klik ▶ Jalankan & Cek — kodenya beneran dieksekusi, bukan tebak-tebakan.

Progress: 0 / 6 kode berhasil dibetulin

🧩 Array Method Match

Method array (map, filter, reduce, dst) paling sering ketuker-tuker fungsinya. Klik satu method di kolom kiri, terus klik deskripsi yang cocok di kolom kanan.


🃏 Flashcard Konsep JS

Istilah-istilah JS (closure, hoisting, callback, dst) sering diomongin tapi jarang dijelasin simpel. Tap kartunya buat lihat penjelasan singkatnya.


🔁 Kilas Balik

Otak gampang lupa kalau materi cuma dibaca sekali. Di sini soal-soal dari Tebak Output dan Urutan Eksekusi muncul acak biar makin nempel di ingatan jangka panjang — coba jawab lagi walau ngerasa udah paham!


✦ Coba Sendiri & 🚀 Mini Project: Todo List

Satu editor buat semuanya: bereksperimen bebas, atau kerjakan tantangan mini project di bawah. Tulis kode di tab HTML / CSS / JavaScript, klik Run, lihat hasilnya di panel preview, dan pantau console.log di panel console di bawahnya.

💡 Tantangan Mini Project — Todo List sederhana (kode awal di bawah sudah jalan, coba kembangkan lagi):
1. Tambah tugas baru lewat input + tombol "Tambah".
2. Klik tugas untuk menandainya selesai (classList.toggle).
3. Tombol "Hapus" di tiap tugas untuk menghapusnya dari daftar.
4. Simpan daftar tugas ke localStorage supaya tidak hilang saat preview di-refresh.
5. (Opsional) Tambahkan filter "Semua / Aktif / Selesai" pakai array methods.
Live Editor
code
preview
console
🔄 Versi baru tersedia