🎨

Frontend Fundamentals

Kursus Gratis — Fullstack Talent

13

Krisis Identitas JS: Keyword `this`

📖 20 menit baca 🏷️ Advanced Core JS

Jika kamu membaca kode programmer asing, kamu pasti sering melihat kata sakti this.nama atau this.umur. Namun ini adalah fitur paling rentan salah kaprah di seluruh penjuru JavaScript!

Di bahasa kuno seperti Java/C++, this selalu merujuk pada "Kelas Tempat Di Mana Aku Lahir". Tapi di JavaScript, Keyword `this` itu sangat plin-plan. Ia tidak peduli di mana ia LAHIR, ia hanya peduli pada SIAPA YANG SEDANG MEMANGGILNYA SAAT INI (Pada detik kode dieksekusi).

Mari kita pelajari kelabilan this dan bagaimana cara kita mengurung paksa identitasnya dengan borgol call, apply, dan bind!

🎭 1. Bukti Plin-Plan Identitas `this`

Mari kita buktikan hukum utama: *"Nilai dari this ditentukan oleh Objek apa yang berada di sebelah kiri Tanda Titik saat fungsi tersebut dipanggil"*.

the-chameleon.js
const userA = { nama: "Andi", sapa: function() { // this merujuk pada objek "Pemanggil" saat dipenghujung jalan console.log(`Halo, saya ${this.nama}!`); } }; const userB = { nama: "Budi" }; ✅ Kasus Normal: userA.sapa(); // Ouput: "Halo, saya Andi!" (Krn "userA" yg memanggil di sebalah kiri titik) ❌ Krisis Identitas: const fungsiNyasar = userA.sapa; // Memutus ikatan fungsi, ditarik ke udara! fungsiNyasar(); // Memanggil tanpa "." di sebelah kiri // Output: "Halo, saya undefined!" 😱 (Krna di alam bebas, 'this' menjadi Global Window) 🔄 Pencurian Identitas: userB.pinjamSuara = userA.sapa; // Budi mencuri fungsi Andi userB.pinjamSuara(); // Output: "Halo, saya Budi!" (Padahal kodenya ditulis di dalam objek Andi 🤯)

💡 Aturan Emas: Jika kamu memanggil sebuah fungsi dengan gaya telanjang bulat alias sendirian: fungsiNyasar(), maka this di dalamnya otomatis terlempar pulang ke wujud Super Semesta (Objek window di Browser, atau menolak jalan dengan status undefined jika Mode Ketat / Strict Mode menyala).

🏹 2. Pengecualian Emas: Arrow Function

Masalah kelabilan this ini begitu kacau sampai membuat banyak programmer frustasi. Karena itulah ES6 merilis Arrow Function =>. Arrow function secara genetik TIDAK memiliki this miliknya sendiri! Ia adalah Anak berbakti yang mengadopsi identitas `this` murni dari lingkungan tempat ia dilahirkan, persis seperti Java/C++.

const mobil = { brand: "Ferrari", nyalakanMesin: function() { // 'this' normal! Ia merujuk pada objek Mobil saat dipanggil 'mobil.nyalakanMesin()' console.log(`Menyalakan ${this.brand}...`); setTimeout(() => { // AJAIB! Kalau pakai function() biasa, 'this' akan jadi Window krn setTimeout berjalan mandiri tanpa "Tanda Titik". // Tapi karena Arrow =>, 'this' akan Mewarisi Bapaknya (Objek Mobil) console.log(`${this.brand} sudah menderu! Vroooom!`); }, 2000); } }; mobil.nyalakanMesin(); // Detik 0: "Menyalakan Ferrari..." // Detik 2: "Ferrari sudah menderu! Vroooom!"

🔗 3. Metode Pemaksaan: Call, Apply, Bind

Lalu bagaimana jika kita terlanjur memiliki fungsi lama (bukan Arrow), tapi kita ingin MEMAKSA fungsi tersebut berganti identitas / meminjam Objek lain secara sengaja? JavaScript (mulai ES5) mempersenjatai kita dengan 3 Metode Pembajakan:

.call()

"Telepon Sekarang"

Menjalankan fungsi SAAT INI JUGA, dengan identitas `this` yang dipaksa, diikuti dengan argumen biasa yang dipisahkan oleh tanda baca Koma (`,`).

sapa.call(objBudi, "Pagi", 100);

.apply()

"Apply Segepok"

Identik persis 100% dengan `call()`. Bedanya hanya satu: alih-alih melempar argumen satu per satu pakai Koma, fungsi ini menelan sebuah rentetan keranjang **Array `[ ]`**.

sapa.apply(objBudi, ["Pagi", 100]);

.bind()

"Borgol & Kemas"

(Paling Populer di React!). Ia **TIDAK menjalankan** fungsinya sekarang. Melainkan memborgol identitas barunya permanen, lalu mencetaknya **sebagai fungsi utuh baru** untuk dipanggil kelak kapan-kapan!

const fnBaru = sapa.bind(objBudi); // ... Nanti dipanggil: fnBaru("Pagi");

🎮 Studi Kasus Interaktif: Pembajakan Data Rumah Sakit

// 1. Mesin Generator Tagihan RS Umum const rsUmum = { nama_rs: "RS Pusat", cetakTagihan: function(poli, harga) { return `[${this.nama_rs}] Pasien poli ${poli} dikenakan biaya Rp ${harga}.`; } }; // 2. Klinik Kecil yang Tiba-tiba Numpang! const klinikDesa = { nama_rs: "Klinik Makmur" }; // JIKA DIMAIN-MAININ PAKAI METODE DI ATAS: // "Klinik Makmur" meminjam mesin cetak milik RS Pusat!

Ubah metode di bawah ini dan lihat bagaimana Klinik Desa menumpang fungsi Cetak dari RS Pusat!

rsUmum.cetakTagihan.call(klinikDesa, 'Gigi', 50000)

▶ [Klinik Makmur] Pasien poli Gigi dikenakan biaya Rp 50000.

rsUmum.cetakTagihan.apply(klinikDesa, ['Mata', 150000])

▶ [Klinik Makmur] Pasien poli Mata dikenakan biaya Rp 150000.

Paling Aman di React
const mesinBaru = rsUmum.cetakTagihan.bind(klinikDesa)

-- Fungsi mesinBaru sudah diciptakan di Memory! --

mesinBaru('Jantung', 9000000)

▶ [Klinik Makmur] Pasien poli Jantung dikenakan biaya Rp 9000000.