Keyword this JavaScript: Sebenarnya Menunjuk ke Apa?

this adalah kata paling sering disalahpahami di JavaScript. Pelajari aturan sederhananya: nilai this ditentukan oleh CARA fungsi dipanggil, bukan di mana ia ditulis — lengkap dengan arrow function, bind, dan jebakan klasiknya.

Diterbitkan 6 Agustus 20269 menit bacaOleh ACY Partner Indonesia
Keyword this JavaScript — yang ditunjuk tergantung cara pemanggilan
300 × 250Slot Iklan TersediaPasang iklan Anda di sini

Sedikit sekali hal di JavaScript yang sebikin pusing keyword this. Orang yang datang dari bahasa lain biasanya mengira this berarti “objek saat ini,” persis seperti di Java atau C#. Di JavaScript aturannya jauh lebih longgar — dan lebih sering bikin kaget. Fungsi yang sama bisa punya this yang menunjuk ke satu hal hari ini, lalu menunjuk ke hal yang benar-benar berbeda besok, cuma gara-gara cara kamu memanggilnya.

Kabar baiknya kusampaikan di depan: begitu aturannya nyantol, this berhenti terasa seperti sihir. Seluruh topik ini ujung-ujungnya cuma satu ide — nilai this ditentukan saat fungsi dipanggil, berdasarkan bagaimana fungsi itu dipanggil, bukan di mana fungsi itu ditulis. Tanamkan kalimat itu baik-baik, sisanya tinggal detail. Yuk kita bangun pelan-pelan.

Kamu bakal lebih gampang mengikuti kalau sudah sempat kenalan dengan fungsi dan objek, soalnya this justru hidup di persimpangan keduanya.

Apa itu this?

this adalah keyword khusus yang otomatis ada di dalam setiap fungsi. Ia menunjuk ke sebuah objek — tapi objek yang mana tidaklah tetap. JavaScript mengisi nilai this dari nol setiap kali fungsinya dijalankan, berdasarkan cara pemanggilannya.

Nah, di situlah semua orang kepleset. Di kebanyakan bahasa, sebuah method itu milik kelasnya dan this selalu menunjuk ke instance-nya. Di JavaScript, fungsi cuma sebuah nilai biasa; ia nggak “dimiliki” oleh apa pun secara permanen. Jadi pertanyaannya bukan “this di dalam fungsi ini artinya apa?” Pertanyaan yang sebenarnya selalu: “fungsi ini dipanggil dengan cara apa?” Jawab itu, dan kamu langsung tahu nilai this.

function tampilkan() {
  console.log(this);
}

Fungsi tampilkan yang sama persis itu bisa mencetak objek window, bisa undefined, bisa juga sebuah objek user — semuanya tergantung di mana ia dipanggil. Di bawah ini kita bakal telusuri setiap cara sebuah fungsi bisa dipanggil, dan this jadi apa di tiap kasusnya.

Empat pola pemanggilan

Ada empat cara umum memanggil fungsi, dan masing-masing menetapkan this secara berbeda. Kuasai keempatnya, kamu sudah menutup hampir semua hal yang bakal kamu temui di kode beneran.

1. Pemanggilan method: this adalah objek sebelum titik

Ketika kamu memanggil fungsi sebagai property dari sebuah objek — objek.method()this jadi objek yang ada di sebelah kiri titik. Ini kasus yang paling intuitif sekaligus yang paling sering kamu pakai.

const user = {
  nama: "John Doe",
  sapa() {
    console.log("Halo, aku " + this.nama);
  },
};

user.sapa();   // "Halo, aku John Doe"

Di dalam sapa, this adalah user, karena pemanggilannya user.sapa()user itulah yang ada sebelum titik. Jadi this.nama membaca user.nama. Sederhana dan gampang ditebak.

Kunci pemahamannya: yang menentukan adalah pemanggilannya, bukan di mana fungsi itu didefinisikan. Coba lihat apa yang terjadi kalau method-nya kita cabut dari objeknya:

const sapaSendiri = user.sapa;
sapaSendiri();   // 💥 this.nama sekarang undefined (atau error)

Fungsinya sama persis, tapi sekarang nggak ada objek di depan titik, jadi this bukan lagi user. Fungsinya nggak berubah — yang berubah cara kita memanggilnya. Contoh satu ini saja sudah jadi inti dari seluruh topik.

2. Pemanggilan fungsi biasa: this adalah undefined (atau objek global)

Ketika kamu memanggil fungsi secara berdiri sendiri — tanpa objek, tanpa titik — nilai this tergantung apakah kamu sedang dalam strict mode atau bukan:

function mandiri() {
  console.log(this);
}

mandiri();
// strict mode (modul, class): undefined
// non-strict (skrip lawas):   objek global (window di browser)

Di JavaScript modern — modul ES, badan class, apa pun yang pakai "use strict" — pemanggilan fungsi biasa menghasilkan this === undefined. Ini justru menolong, karena bug yang tadinya diam-diam jadi error yang berisik, bukan diam-diam menulis ke objek global.

Masalah this yang hilang

Inilah bug this yang paling sering terjadi. Kamu mencabut sebuah method dari objeknya lalu memanggilnya belakangan — lewat sebuah variabel, sebuah callback, atau lewat setTimeout — dan tiba-tiba this lenyap:

const user = { nama: "John Doe", sapa() { return this.nama; } };

setTimeout(user.sapa, 1000);   // di sini this BUKAN user!

setTimeout tidak memanggilnya sebagai user.sapa() — ia menyimpan fungsinya lalu nanti memanggilnya secara polos, tanpa objek di depan titik. Akibatnya this bukan lagi user. Cara perbaikannya (arrow function, bind) kita bahas di bawah — tapi yang penting dulu, kenali polanya: setiap kali sebuah method dioper ke tempat lain lalu dipanggil di sana, nilai this-nya terancam ikut hilang.

3. Pemanggilan constructor: this adalah objek yang baru dibuat

Ketika kamu memanggil fungsi dengan keyword new, JavaScript membuat satu objek kosong yang baru lalu mengarahkan this ke objek itu. Fungsinya mengisi objek tersebut, dan (selama kamu tidak me-return sesuatu yang lain) new otomatis mengembalikannya untukmu.

function User(nama) {
  this.nama = nama;
  this.peran = "member";
}

const u = new User("Jane Doe");
console.log(u.nama);   // "Jane Doe"
console.log(u.peran);  // "member"

Di sini this adalah objek baru yang sedang dirakit. Hal yang sama terjadi di dalam constructor sebuah class — class pada dasarnya cuma sintaks yang lebih rapi di atas mekanisme persis ini. Kalau kamu pernah memakai new Date() atau new Map(), sebenarnya kamu sudah mengandalkan pola ini tanpa sadar.

4. Pemanggilan eksplisit: kamu sendiri yang memilih this lewat call, apply, bind

Kadang kamu ingin menentukan this sendiri, terlepas dari bagaimana fungsi itu biasanya dipanggil. JavaScript memberi tiga method pada setiap fungsi khusus untuk itu: call, apply, dan bind.

function sapa(salam) {
  console.log(salam + ", " + this.nama);
}

const orang = { nama: "John Doe" };

sapa.call(orang, "Halo");     // "Halo, John Doe"
sapa.apply(orang, ["Hai"]);   // "Hai, John Doe"

const terikat = sapa.bind(orang);
terikat("Hei");               // "Hei, John Doe"

call dan apply menjalankan fungsinya saat itu juga dengan this yang kamu tentukan — bedanya cuma call menerima argumen satu per satu, sedangkan apply menerimanya dalam bentuk array. bind beda lagi: ia tidak memanggil fungsinya, melainkan mengembalikan fungsi baru dengan this yang sudah dikunci permanen ke nilai yang kamu berikan. Fungsi hasil itu bakal terus memegang this tersebut, apa pun cara ia dipanggil nanti — dan justru itulah yang membuat bind jadi solusi klasik untuk masalah “this yang hilang”.

Cara ingat call vs apply

call dan apply tugasnya sama; yang beda cuma cara mengoper argumen. Pengait kecil biar gampang ingat: apply menerima array. call menyebar argumennya: fn.call(thisArg, a, b, c). apply membungkusnya: fn.apply(thisArg, [a, b, c]). Dengan adanya spread operator (...), apply jarang dibutuhkan lagi — fn.call(thisArg, ...args) sudah menutup kebutuhannya.

Arrow function: this diwarisi, bukan diatur ulang

Arrow function mematahkan semua aturan di atas — dengan sengaja, dan dengan menolong. Arrow function tidak punya this sendiri. Ia tidak peduli bagaimana ia dipanggil. Sebagai gantinya, ia meminjam this dari kode di sekitarnya tempat ia ditulis — itulah lexical scope. Inilah satu-satunya tempat di mana “di mana ia ditulis” benar-benar berpengaruh.

Kedengarannya abstrak sampai kamu lihat masalah yang dipecahkannya. Ini salah satu bug nyata yang paling sering muncul:

const timer = {
  detik: 0,
  mulai() {
    setInterval(function () {
      this.detik++;            // 💥 di sini this BUKAN timer
      console.log(this.detik); // NaN, terus-terusan
    }, 1000);
  },
};

Callback di dalam setInterval itu pemanggilan fungsi biasa, jadi this-nya undefined (atau objek global), bukan timer. Akibatnya operasi tambahnya diam-diam gagal. Sekarang kita ganti dengan arrow function:

const timer = {
  detik: 0,
  mulai() {
    setInterval(() => {
      this.detik++;            // ✅ this adalah timer
      console.log(this.detik); // 1, 2, 3, ...
    }, 1000);
  },
};

Arrow function tadi tidak punya this sendiri, jadi this di dalamnya sama dengan this yang berlaku di mulai — dan mulai dipanggil sebagai timer.mulai(), jadi this-nya timer. Si arrow tinggal mewarisinya. Itulah kenapa arrow jadi pilihan utama untuk callback yang ada di dalam method.

Jangan pakai arrow function sebagai method objek

Karena arrow mewarisi this, bukan punya this sendiri, ia justru jadi pilihan yang salah untuk method utama pada sebuah objek:

const user = {
  nama: "John Doe",
  sapa: () => {
    console.log(this.nama);   // undefined — BUKAN user
  },
};
user.sapa();

Di sini arrow mewarisi this dari scope di sekitarnya (modul atau global), bukan dari user — jadi this.nama salah. Patokannya: pakai fungsi biasa (atau penulisan singkat method) untuk method objek supaya this bisa terikat ke objeknya, dan pakai arrow function untuk callback yang berada di dalam method tersebut supaya ia mewarisi this yang benar.

Model mental yang utuh

Gabungkan semuanya, dan kamu bisa membaca this di kode mana pun cukup dengan satu pertanyaan di titik pemanggilan — fungsi ini dipanggil dengan cara apa? Telusuri daftarnya berurutan:

// 1. new Fn()        → this adalah objek baru yang dibuat
// 2. obj.fn()        → this adalah obj (yang ada di depan titik)
// 3. fn.call(x) dst. → this adalah x (apa pun yang kamu oper)
// 4. fn()            → this adalah undefined (strict) / global (sloppy)
// 5. arrow function  → abaikan semua di atas; this datang dari scope
//                      di sekitar tempat arrow itu ditulis

Perhatikan, arrow function berada di luar daftar — ia memilih keluar dari seluruh mekanisme dan justru meminjam dari sekitarnya. Untuk fungsi jenis lain, jawabannya ada di titik pemanggilan, bukan di tempat definisinya. Kalau this bikin kamu bingung, jangan baca ulang badan fungsinya. Cari di mana ia dipanggil, lalu cocokkan dengan kasus-kasus di atas. Jawabannya selalu ada di sana.

Kapan memakai yang mana

Beberapa kebiasaan praktis yang bikin this nggak ganggu kerjamu:

  • Method objek → fungsi biasa atau penulisan singkat method (sapa() { ... }). Mereka butuh this sendiri supaya bisa terikat ke objeknya.
  • Callback di dalam method → arrow function. Mereka mewarisi this milik method-nya, dan itu hampir selalu yang kamu mau.
  • Mengoper method sebagai callback → ikat dulu (this.handle = this.handle.bind(this)) atau bungkus dalam arrow (() => this.handle()), supaya this-nya selamat sampai tujuan.
  • Class modern → entah definisikan handler sebagai class field berupa arrow function, atau bind di constructor. Keduanya menjaga this tetap menunjuk ke instance.

Kalau kamu pernah mengulik scope dan closure, perhatikan kontrasnya: variabel biasa diselesaikan secara lexical (berdasarkan tempat kodenya ditulis), tapi this untuk fungsi biasa diselesaikan secara dinamis (berdasarkan cara pemanggilannya). Arrow function adalah jembatannya — ia membuat this berperilaku lexical, layaknya variabel biasa. Perbedaan satu itu menjelaskan sebagian besar kebingungan orang soal this.

Penutup

Keyword this cuma terasa kacau sampai kamu meresapi satu aturannya:

  • this ditentukan oleh cara sebuah fungsi dipanggil, bukan di mana ia didefinisikan. Kalau ragu, lihat titik pemanggilannya.
  • Pemanggilan method (obj.fn()) → this adalah objek di depan titik.
  • Pemanggilan biasa (fn()) → this adalah undefined dalam strict mode, atau objek global di luar itu.
  • Pemanggilan constructor (new Fn()) → this adalah objek yang baru dibuat.
  • Pemanggilan eksplisit (call, apply, bind) → this adalah apa pun yang kamu oper; bind menguncinya permanen ke dalam sebuah fungsi baru.
  • Arrow function tidak punya this sendiri — ia mewarisinya dari scope di sekitarnya. Cocok untuk callback di dalam method; salah kalau dipakai sebagai method objeknya langsung.

Kuasai kasus-kasus itu, dan kata yang paling “ajaib” di JavaScript pun berubah jadi salah satu yang paling gampang ditebak. Lain kali this bernilai undefined, kamu langsung tahu harus mencari ke mana — dan biasanya kamu beresin dalam hitungan detik dengan sebuah arrow function atau sebuah bind.

Tag:javascriptfrontendthisbindingmenengah
728 × 90Slot Iklan TersediaPasang iklan Anda di sini

Artikel Terkait

Lihat Semua Artikel

Artikel yang Mungkin Kamu Suka

Apa Itu Framework Frontend? — chip kode dengan tag komponen
Frontend / Dasar

Apa Itu Framework Frontend?

Penjelasan ramah untuk pemula tentang apa itu framework frontend, kenapa mereka ada, masalah apa yang mereka selesaikan dibanding JavaScript biasa, dan kapan kamu memang sebaiknya memakainya.

20 Sep 20268 menit baca
Sampul fundamentals frontend bertuliskan Apa Itu Frontend dan HTML + CSS + JS
Frontend / Dasar

Apa Itu Frontend Development?

Panduan ramah pemula tentang frontend development: bagian website yang kamu lihat dan klik secara langsung. Pahami cara kerja HTML, CSS, dan JavaScript, serta bedanya frontend dengan backend.

20 Sep 20268 menit baca
Ilustrasi sampul untuk Apa yang Dikerjakan Frontend Developer
Frontend / Dasar

Apa yang Dikerjakan Frontend Developer: Panduan untuk Pemula

Penjelasan ramah pemula tentang apa yang sebenarnya dikerjakan frontend developer setiap hari: mengubah desain jadi antarmuka yang berfungsi, membangun UI yang bisa dipakai ulang, sampai urusan responsif, aksesibilitas, dan kecepatan.

20 Sep 20269 menit baca
Kartu judul bertuliskan Styling dan Interaktivitas di atas latar biru gelap ACY Partner
Frontend / Dasar

Cara Kerja Styling dan Interaktivitas

Penjelasan ramah pemula soal bagaimana CSS menyulap HTML polos jadi tampilan rapi, dan bagaimana JavaScript menambahkan perilaku — pola berpikir struktur, gaya, perilaku saat membangun halaman web.

20 Sep 20268 menit baca
Tiga lapisan front-end menyatu di satu halaman web
Frontend / Dasar

Cara HTML, CSS, dan JavaScript Bekerja Bersama

Panduan praktis untuk pemula: bikin satu tombol kecil, beri struktur dengan HTML, tampilan dengan CSS, dan perilaku dengan JavaScript, lalu lihat ketiga lapisan ini bekerja sama di halaman nyata.

20 Sep 20268 menit baca
Sampul ikhtisar praktik terbaik frontend
Frontend / Dasar

Ikhtisar Praktik Terbaik Frontend

Peta ringkas tentang apa itu frontend yang baik — HTML bermakna, CSS rapi, JavaScript secukupnya, desain responsif, performa, dan progressive enhancement, lengkap dengan arahan untuk mendalaminya.

20 Sep 20268 menit baca