Lompat ke konten
Kembali ke modul

JavaScript: Bahasanya · 8/12

Closure

Function mengingat tempat ia dilahirkan. Satu ide ini menggerakkan hooks, callback, dan private state.

Baca 30 menit

Setelah pelajaran ini kamu bisa

  • Menjelaskan apa itu closure dalam satu kalimat
  • Memakai closure untuk menjaga state tetap privat
  • Mengenali jebakan klasik variable loop
  • Menjelaskan kenapa React hooks bergantung pada ini

Closure adalah function yang mengingat variable dari tempat ia dibuat, bahkan setelah tempat itu selesai dijalankan. Itu seluruh idenya. Semua di bawah ini hanyalah konsekuensinya.

Coba sendiri

makeCounter langsung selesai dijalankan, tapi `count` tetap hidup. Itulah closure.

Hasil

Tekan Jalankan untuk melihat hasilnya.

Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.

Perhatikan dua hal. Pertama, count hidup lebih lama dari pemanggilan function yang membuatnya. Kedua, setiap pemanggilan makeCounter menghasilkan count yang terpisah — closure menangkap sekumpulan variable tertentu, bukan sebuah global bersama.

State privat

Coba sendiri

Hasil

Tekan Jalankan untuk melihat hasilnya.

Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.

Jebakan loop yang klasik

Karena closure melihat variable hidup dan bukan salinannya, penghitung loop var yang dipakai bersama semua callback berakhir di nilai terakhirnya. let memperbaikinya dengan membuat ikatan baru di setiap iterasi.

Coba sendiri

Pertanyaan interview JavaScript paling terkenal. Tebak kedua loop-nya.

Hasil

Tekan Jalankan untuk melihat hasilnya.

Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.

Dengan var hanya ada satu i untuk seluruh loop; saat function-nya dijalankan, nilainya sudah 3. Dengan let setiap iterasi membuat j baru, jadi setiap function menutupi miliknya sendiri. Ini alasan konkret kenapa let menggantikan var.

Closure dan kode async

Coba sendiri

Hasil

Tekan Jalankan untuk melihat hasilnya.

Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.

Tugas praktik

Tulis once(fn) yang mengembalikan function terbungkus yang memanggil fn hanya di kali pertama, dan di pemanggilan berikutnya mengembalikan hasil pertama tanpa memanggil fn lagi. Pakai closure untuk mengingat apakah ia sudah pernah jalan. Uji dengan function yang mencetak log saat dieksekusi.

Hasil yang diharapkan

Log di dalamnya muncul tepat satu kali, sebanyak apa pun pemanggilannya.

Tampilkan contoh solusi

Coba dulu minimal sepuluh menit sebelum membuka ini. Bagian yang terasa susah itu justru yang mengajari kamu.

function once(fn) {
  let called = false;
  let result;

  return function (...args) {
    if (!called) {
      called = true;
      result = fn(...args);
    }
    return result;
  };
}

const setup = once((label) => {
  console.log("running setup for", label);
  return label.toUpperCase();
});

console.log(setup("database"));
console.log(setup("database"));
console.log(setup("anything else"));

Cek pemahaman

for (var i = 0; i < 3; i++) fns.push(() => i). Apa hasil dari fns.map(f => f())?

Pilih jawaban dulu