Setelah enam chapter menulis function utuh, wajar bila tanda kurung dan kurung kurawal mulai terasa panjang — apalagi untuk function kecil yang isinya satu perhitungan. ECMAScript 2015 menghadirkan arrow function: function ditulis dengan tanda panah =>, jauh lebih ringkas, dan sangat cocok untuk function pendek yang dikirim sebagai nilai. Di balik peringkatannya yang menggiurkan, ada satu perbedaan perilaku yang wajib dipahami sejak awal: arrow function tidak memiliki this sendiri.

Chapter ini membuktikan dua hal sekaligus. Pertama, bahwa arrow function dan regular function menghasilkan keluaran sama untuk pekerjaan biasa. Kedua — dan terpenting — bahwa keduanya bersikap berbeda saat menjadi method sebuah object, dengan pengukuran yang jujur di Node.

Sintaks Ringkas dan Implicit Return #

Bentuk paling lengkap arrow function menyerupai function expression: parameter di tanda kurung, tanda =>, lalu badan di kurung kurawal. Dari situ ada dua pintasan. Bila badan hanya berisi satu ekspresi, kurung kurawal dan kata return boleh ditanggalkan — hasil ekspresinya otomatis dikirim; gaya ini disebut implicit return. Bila parameternya hanya satu, tanda kurungnya pun boleh ditanggalkan.

Berkas berikut membandingkan keduanya secara berdampingan, lalu menguji perilaku this saat arrow dipakai sebagai method object:

// perbandingan-arrow.js
// Arrow function: sintaks ringkas, implicit return, dan perilaku this.

// --- 1. regular function vs arrow function, hasil sama ---
const dobelReguler = function (angka) {
  return angka * 2;
};

const dobelArrow = (angka) => {
  return angka * 2;
};

console.log("Reguler:", dobelReguler(5));
console.log("Arrow  :", dobelArrow(5));

// --- 2. implicit return: tanpa kurung kurawal, tanpa kata return ---
const dobelRingkas = (angka) => angka * 2;
const sapa = (nama) => "Halo, " + nama + "!";
console.log("dobelRingkas(9):", dobelRingkas(9));
console.log(sapa("Siti"));

// --- 3. satu parameter boleh ditulis tanpa tanda kurung ---
const kuadrat = angka => angka * angka;
console.log("kuadrat(6):", kuadrat(6));

// --- 4. arrow tidak punya this sendiri ---
const profil = {
  nama: "Budi",
  sapaReguler: function () {
    console.log("Reguler - Halo, " + this.nama);
  },
  sapaArrow: () => {
    console.log("Arrow   - Halo, " + this.nama);
  },
  cekThisReguler: function () {
    console.log("Reguler, this === profil:", this === profil);
  },
  cekThisArrow: () => {
    console.log("Arrow,   this === profil:", this === profil);
  },
};

profil.sapaReguler();
profil.sapaArrow();
profil.cekThisReguler();
profil.cekThisArrow();

Output yang Dihasilkan:

text
Reguler: 10
Arrow  : 10
dobelRingkas(9): 18
Halo, Siti!
kuadrat(6): 36
Reguler - Halo, Budi
Arrow   - Halo, undefined
Reguler, this === profil: true
Arrow,   this === profil: false

Mari kita telaah apa yang terjadi pada baris-baris kode di atas:

  1. Baris 5–11 (dobelReguler dan dobelArrow): kedua function melakukan pekerjaan yang persis sama dan menghasilkan 10. Pada tingkat ini, => hanyalah gaya penulisan.
  2. Baris 17–18 (dobelRingkas dan sapa): bentuk implicit return. Tidak ada kurung kurawal dan tidak ada kata return, tetapi hasil ekspresi tetap dikirim ke pemanggil — dobelRingkas(9) bernilai 18.
  3. Baris 23 (const kuadrat = angka => angka * angka;): dengan satu parameter, tanda kurungnya boleh dilepas. Dua pintasan tadi bisa digabung, dan kebanyakan arrow function di kode nyata ditulis dalam bentuk seminimal ini.
  4. Baris 29–30 (sapaReguler): regular function yang dipanggil sebagai method (profil.sapaReguler()) mendapat this merujuk ke object pemiliknya — profil. Karena itu this.nama terbaca sebagai Budi.
  5. Baris 32–34 (sapaArrow): arrow function tidak punya this sendiri. this di dalamnya diambil dari lingkaran luar tempat arrow itu ditulis — bukan dari object pemanggil. Hasilnya Arrow - Halo, undefined.
  6. Baris 35–40 (cekThisReguler dan cekThisArrow): pengukuran yang lebih teliti. this === profil bernilai true untuk regular function dan false untuk arrow — bukti kuantitatif bahwa arrow sama sekali tidak menerima profil sebagai this.

Membaca this yang Jujur di Node #

Baris 33 dan 39 menimbulkan pertanyaan wajar: “lalu this milik arrow itu merujuk ke apa?” Jawabannya bergantung pada lingkaran luar tempat arrow ditulis. Pada berkas contoh, arrow ditulis di tingkat atas berkas script Node; di sana this merujuk ke object module milik berkas tersebut — object yang kosong. Karena itu this.nama menghasilkan undefined dan perbandingannya terhadap profil bernilai false.

Rumusnya tidak berubah di lingkungan lain; hanya isi this lingkaran luarnya yang berbeda. Di berkas module ES (.mjs), this tingkat atas bernilai undefined, sehingga this.nama di arrow yang sama bahkan memunculkan error TypeError: Cannot read properties of undefined (reading 'nama') — kita uji langsung dan pesan itulah yang muncul. Di browser non-module, this tingkat atas adalah window; this.nama kembali menghasilkan undefined. Tiga lingkungan, satu kesimpulan: this arrow tidak pernah merujuk ke object pemanggilnya.

Konsekuensi praktisnya tegas — arrow function tidak cocok menjadi method object yang membutuhkan this. Untuk method, pakai regular function; untuk function pendek yang tidak menyentuh this, arrow justru pilihan yang disukai.

Aturan “mewarisi this lingkar luarnya” juga membuka satu pola yang sah dan berguna: arrow yang ditulis di dalam method biasa. Method menerima this dari object-nya, dan arrow di dalam badannya mewarisinya — sehingga this tetap merujuk object yang benar:

js
const akun = {
  nama: "Siti",
  sapa: function () {
    const sapaanArrow = () => "Halo, " + this.nama;
    return sapaanArrow();
  },
};

console.log(akun.sapa());

Output yang Dihasilkan:

text
Halo, Siti

sapaanArrow tidak punya this sendiri, jadi ia meminjam this milik sapa — yang berisi akun. Inilah alasan arrow function disukai di dalam callback: function pendek yang dikirim dari dalam sebuah method tetap bisa membaca this milik method tersebut. Yang salah bukan arrow-nya, melainkan menempatkan arrow sebagai method utama.

Satu batasan lain yang jarang disadari: arrow function tidak bisa dipakai sebagai constructor. Pemanggilan new BuatPoin(1, 2) terhadap arrow function memunculkan TypeError: BuatPoin is not a constructor. Konsep new sendiri baru kita temui di section Object-Oriented JavaScript; untuk sekarang cukup diingat bahwa arrow bukan pengganti total untuk regular function.

Kapan Memakai Arrow #

Seluruh perbedaan yang sudah diuji bisa dirangkum dalam satu tabel:

AspekRegular functionArrow function
Sintaksfunction (a) { return a * 2; }(a) => a * 2
this sendiriya — dari object pemanggiltidak — mewarisi lingkar luarnya
arguments objecttersediatidak tersedia
Menjadi method objectcocoktidak cocok bila butuh this
Dipakai dengan newbisaditolak — TypeError
Hoisting (bila declaration)yatidak berlaku — arrow selalu berbentuk ekspresi

Aturan praktis yang sehat mengikuti tabel itu:

  • Pakai arrow untuk function pendek yang menerima data, menghasilkan nilai, dan tidak menyentuh this — terutama yang dikirim sebagai callback (topik chapter berikutnya).
  • Pakai regular function untuk method object dan untuk function yang butuh arguments object.
  • Jaga implicit return tetap satu baris ekspresi. Begitu logikanya butuh beberapa statement, kembalikan kurung kurawal dan tulis return eksplisit.

Dengan arrow function, kotak peralatan function kita lengkap secara sintaks. Chapter berikutnya memakainya untuk pola yang paling khas di JavaScript: mengirim function sebagai argument agar dijalankan oleh function lain — pola callback.

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

perbandingan-arrow.js

Unduh berkas
javascript
// perbandingan-arrow.js
// Arrow function: sintaks ringkas, implicit return, dan perilaku this.

// --- 1. regular function vs arrow function, hasil sama ---
const dobelReguler = function (angka) {
  return angka * 2;
};

const dobelArrow = (angka) => {
  return angka * 2;
};

console.log("Reguler:", dobelReguler(5));
console.log("Arrow  :", dobelArrow(5));

// --- 2. implicit return: tanpa kurung kurawal, tanpa kata return ---
const dobelRingkas = (angka) => angka * 2;
const sapa = (nama) => "Halo, " + nama + "!";
console.log("dobelRingkas(9):", dobelRingkas(9));
console.log(sapa("Siti"));

// --- 3. satu parameter boleh ditulis tanpa tanda kurung ---
const kuadrat = angka => angka * angka;
console.log("kuadrat(6):", kuadrat(6));

// --- 4. arrow tidak punya this sendiri ---
const profil = {
  nama: "Budi",
  sapaReguler: function () {
    console.log("Reguler - Halo, " + this.nama);
  },
  sapaArrow: () => {
    console.log("Arrow   - Halo, " + this.nama);
  },
  cekThisReguler: function () {
    console.log("Reguler, this === profil:", this === profil);
  },
  cekThisArrow: () => {
    console.log("Arrow,   this === profil:", this === profil);
  },
};

profil.sapaReguler();
profil.sapaArrow();
profil.cekThisReguler();
profil.cekThisArrow();