this merujuk ke objek yang "memiliki" fungsi saat dijalankan. Nilainya berubah tergantung bagaimana fungsi dipanggil.
1. Di method objek — this = objek pemilik:
const user = {
nama: "Budi",
sapa() { return "Halo, " + this.nama; }
};
user.sapa(); // "Halo, Budi"
2. Di fungsi biasa — this = undefined (strict) atau window:
function tampil() { return this; }
tampil(); // undefined (strict mode)
3. Arrow function — this dari scope luar:
const obj = {
nama: "Ani",
sapa: () => "Halo, " + this.nama // this = scope luar, bukan obj!
};
4. Mengatur this manual:
call(obj, arg1, arg2)— panggil denganthis= objapply(obj, [args])— sama, tapi args dalam arraybind(obj)— buat fungsi baru denganthisterikat
Kesalahan yang Sering Terjadi
Lihat kode ini — apa yang salah?
const tombol = {
label: "Kirim",
attach() {
document.getElementById("btn")
.addEventListener("click", function() {
console.log(this.label); // undefined 😱
});
}
};
function() {...} sebagai callback punya this-nya sendiri (bukan tombol). Jadi this.label jadi undefined.
Perbaikan: pakai arrow function yang mewarisi this dari scope luar:
document.getElementById("btn")
.addEventListener("click", () => {
console.log(this.label); // "Kirim" ✅
});
🎭 Analogi sehari-hari
this itu kayak kata "aku" pas lagi ngobrol. Yang dimaksud "aku" tergantung SIAPA YANG NGOMONG, bukan tergantung di mana kalimat itu ditulis. Pas Budi ngomong "aku lapar" → "aku" = Budi. Pas Ani yang ngomong kalimat sama → "aku" = Ani. Pas user.sapa() dipanggil, this = user. Tapi pas method-nya dilepas dari pemiliknya (const f = user.sapa; f()) — kayak kalimat tanpa subjek jelas yang ngucap, this jadi bingung sendiri (undefined).
Arrow function beda — dia kayak kutipan dari obrolan sebelumnya: "aku" di kutipan ngacu ke yang ngomong di obrolan asli, bukan yang baru ngutip sekarang. Lexical scope, gak bisa diubah.
Aturan emas yang wajib dihafal: cek cara fungsi DIPANGGIL, bukan tempat fungsi DITULIS.
⚠️ Jebakan yang sering ditemui:
- Method dilepas dari object —
const sapa = user.sapa; sapa()bikinthisjadiundefined. Pakaiuser.sapa.bind(user).- Arrow di method object —
obj = { foo: () => this.bar }→thismengarah ke scope luar (sering window/undefined), bukan obj. Pakaifunction()syntax.thisdi setTimeout callback —setTimeout(this.foo, 1000)putuskan binding. PakaisetTimeout(() => this.foo(), 1000)atau.bind(this).thisdi event handler —function()callback →this= element yang trigger event. Arrow →thisdari scope luar. Pilih sengaja.- Class method tidak auto-bind —
<button onClick={this.handleClick}>di React class component sering kena bug. Pakai class property arrowhandleClick = () => {}atau bind di constructor.
Tips: Gunakan arrow function di callback agar
thistidak berubah. Sebaliknya, pakaifunction()biasa kalau kamu sengaja mauthismengikuti pemanggilnya (misalnya method object atauaddEventListenerdi mana kamu butuh element sebagaithis).
TL;DR: Nilai this ditentukan cara pemanggilan, bukan tempat penulisan. obj.method() → this = obj. new Foo() → instance baru. Fungsi biasa fn() → undefined (strict). Arrow function tidak punya this sendiri — diambil dari scope luar. Override manual via call/apply/bind. Method dilepas dari object (const f = obj.sapa) langsung putus binding — pakai .bind(obj) atau panggil lewat object aslinya.