Class Adalah Cetak Biru untuk Objek
Class menjelaskan bentuk dan perilaku sejenis objek. Kamu mendefinisikan cetak birunya sekali, lalu mencetak instance sebanyak yang kamu perlukan. Setiap instance membawa datanya sendiri, tetapi memakai method yang sama.
Bentuk dasarnya:
class User { ... } mendefinisikan cetak birunya. new User(...) membuat sebuah instance. Setiap instance mendapat name dan email sendiri, tetapi keduanya memakai satu method greet yang sama, yang didefinisikan di class.
Dua instance, dua set data, satu set method. Itulah intinya.
constructor Menyiapkan Setiap Instance
constructor adalah method khusus yang berjalan tepat sekali untuk setiap instance, persis saat new membuatnya. Tugasnya menginisialisasi objek yang baru dibuat, biasanya dengan menyalin argumen ke this:
this di dalam constructor merujuk ke instance baru yang sedang dibangun. Menulis this.x = x menaruh x di objek tersebut. Setiap panggilan new Point(...) mendapat this sendiri, jadi juga punya x dan y sendiri.
Kalau kamu tidak menulis constructor, JavaScript memberimu constructor kosong secara gratis. Kamu hanya perlu menulisnya saat memang ada persiapan yang harus dilakukan.
new yang Menjalankan Seluruh Mesinnya
Memanggil class tanpa new akan memunculkan error:
const p = Point(3, 4);
// TypeError: Class constructor Point cannot be invoked without 'new'
Itu disengaja. new melakukan empat hal secara berurutan:
- Membuat objek kosong yang baru.
- Menautkannya ke prototype class (tempat method berada).
- Menjalankan
constructordenganthisterikat ke objek baru itu. - Mengembalikan objek baru tersebut.
Tanpa new, semua itu tidak terjadi. Class memaksakan aturan ini agar kamu tidak lupa tanpa sengaja. Ini peningkatan nyata dibandingkan masa sebelum class, saat lupa menulis new bisa diam-diam merusak objek global.
Method Dipakai Bersama, Field Milik Tiap Instance
Method yang didefinisikan di dalam isi class berada di prototype: satu salinan yang dipakai bersama oleh setiap instance. Field instance (apa pun yang kamu simpan ke this) dimiliki masing-masing instance, berupa salinan terpisah setiap kali.
Kedua instance punya count sendiri, jadi menambah satu tidak memengaruhi yang lain. Tetapi a.increment dan b.increment benar-benar fungsi yang sama: disimpan sekali di prototype, lalu dicari setiap kali kamu memanggilnya pada sebuah instance. Itulah sebabnya class hemat saat jumlahnya banyak: seribu instance tidak membuat seribu salinan dari setiap method.
Class Field
Kamu bisa mendeklarasikan field instance di bagian atas isi class, di luar constructor:
Deklarasi field berjalan sebelum isi constructor, seolah-olah ditulis di bagian atas constructor. Berguna saat nilai awalnya tidak bergantung pada argumen constructor, dan lebih rapi daripada memenuhi constructor dengan this.count = 0; this.step = 1;.
Kalau nilainya memang bergantung pada argumen, tetap lakukan penugasannya di constructor, tempat argumen-argumen itu tersedia.
Getter dan Setter
Getter atau setter terlihat seperti method tetapi berperilaku seperti akses property. Kamu membaca atau mengisinya tanpa kurung, dan method-nya berjalan di balik layar:
Perhatikan cara pemanggilannya: t.fahrenheit (tanpa kurung) membaca getter, t.fahrenheit = 100 memicu setter. Dari luar, fahrenheit terlihat seperti property biasa, padahal nilainya dihitung saat itu juga dari celsius.
Getter sangat cocok untuk nilai turunan. Setter sangat cocok untuk memvalidasi atau menormalkan nilai saat diisi. Jangan berlebihan memakainya: kalau sebuah getter mahal dijalankan, pembaca akan kaget bahwa sebuah "akses property" ternyata melakukan pekerjaan sungguhan.
Method Singkat, Nama Terhitung, dan this
Definisi method dalam class memakai sintaks singkat: tanpa kata kunci function, tanpa : di antara nama dan isinya:
Mengembalikan this dari add memungkinkan method chaining: setiap panggilan mengembalikan instance yang sama sehingga method berikutnya bisa dijalankan padanya.
Satu jebakan: method tidak otomatis terikat ke instance-nya. Kalau kamu mengambil sebuah method lalu memanggilnya sendirian, this akan hilang:
Memanggil g.hello() berhasil karena . yang menyediakan this. Memanggil fn() sendirian tidak berhasil. Kalau kamu butuh method terpisah yang sudah terikat (kasus umum di event handler), lakukan bind di constructor atau pakai class field berupa arrow function: hello = () => \Hi, ${this.name}`;`.
Contoh Kecil yang Berfungsi
Menggabungkan semua bagiannya: field, constructor, method, dan sebuah getter:
Mudah dipahami sekilas: class ini menjelaskan dengan tepat apa itu BankAccount dan apa yang bisa dilakukannya.
Class Sebenarnya Adalah Fungsi
Satu hal yang layak kamu pahami betul: class sebagian besar hanyalah sintaks pemanis. Di baliknya, class adalah fungsi, tepatnya fungsi constructor, dan method-nya berada di ClassName.prototype:
typeof User bernilai "function". greet berada di User.prototype. Instance mencari greet melalui rantai prototype, mekanisme yang sama yang sudah ada di bahasa ini sejak awal. Class hanya memberimu sintaks yang rapi untuk menyiapkannya.
Model mental itu akan berguna nanti: inheritance, instanceof, dan debug rantai prototype semuanya jadi lebih masuk akal begitu kamu ingat bahwa class adalah fungsi dengan method yang tergantung di prototype-nya.
Berikutnya: Inheritance
Sejauh ini setiap class berdiri sendiri. Kebanyakan desain sungguhan membangun hierarki class: Dog yang merupakan jenis Animal, AdminUser yang merupakan jenis User. Kata kunci extends dan super menangani hal itu, dan keduanya dibahas berikutnya.
Pertanyaan yang sering diajukan
Bagaimana cara membuat class di JavaScript?
Pakai kata kunci class diikuti nama, lalu blok berisi method constructor dan method lainnya. Buat instance dengan new ClassName(...). Contoh: class User { constructor(name) { this.name = name; } } lalu new User('Ada').
Apa fungsi constructor di class JavaScript?
constructor berjalan sekali saat kamu memanggil new ClassName(...). Tugasnya menyiapkan instance baru, biasanya dengan menyimpan argumen ke this sebagai property instance. Kalau kamu tidak menulisnya, JavaScript otomatis memberimu constructor default yang kosong.
Apa bedanya class dan fungsi di JavaScript?
Di baliknya, class adalah fungsi, tepatnya fungsi constructor dengan method yang terpasang di prototype-nya. Kata kunci class sebagian besar hanyalah sintaks pemanis, tetapi ia mewajibkan pemanggilan dengan new, mendukung extends dengan rapi, dan membuat method tidak bisa di-enumerate. Untuk kode baru, utamakan class daripada fungsi constructor yang ditulis manual.