Class dan OOP di JavaScript
Pemrograman berorientasi object: class, constructor, method, inheritance dengan extends, dan enkapsulasi.
Cetakan untuk object
Class adalah cetakan (blueprint) untuk membuat banyak object dengan struktur sama. Daripada menulis object satu per satu, definisikan class sekali lalu cetak sebanyak dibutuhkan.
class Kucing {
constructor(nama, warna) {
this.nama = nama;
this.warna = warna;
}
bersuara() {
console.log(this.nama + " mengeong: meong!");
}
}
let k1 = new Kucing("Mochi", "putih");
let k2 = new Kucing("Milo", "oren");
k1.bersuara(); // "Mochi mengeong: meong!"
k2.bersuara(); // "Milo mengeong: meong!"constructor jalan otomatis saat new dipanggil, bertugas mengisi data awal. Method didefinisikan tanpa kata function.
Inheritance: mewarisi dengan extends
Class bisa mewarisi class lain. Class anak mendapat semua method class induk, plus bisa menambah atau meng-override:
class Hewan {
constructor(nama) {
this.nama = nama;
}
bersuara() {
console.log(this.nama + " bersuara");
}
}
class Anjing extends Hewan {
bersuara() { // override
console.log(this.nama + " menggonggong: guk guk!");
}
jagaRumah() { // method tambahan
console.log(this.nama + " menjaga rumah");
}
}
let d = new Anjing("Bruno");
d.bersuara(); // "Bruno menggonggong: guk guk!"
d.jagaRumah(); // "Bruno menjaga rumah"super: panggil induk
Di constructor anak, super() wajib dipanggil sebelum memakai this:
class KucingAnggora extends Kucing {
constructor(nama, warna, panjangBulu) {
super(nama, warna); // panggil constructor Kucing
this.panjangBulu = panjangBulu;
}
}super juga bisa memanggil method induk yang di-override: super.bersuara().
Private field dengan
JavaScript modern mendukung field privat dengan awalan #:
class Tabungan {
#saldo = 0; // privat, tidak bisa diakses dari luar
setor(n) { this.#saldo += n; }
cek() { return this.#saldo; }
}
let t = new Tabungan();
t.setor(100);
console.log(t.cek()); // 100
console.log(t.#saldo); // ERROR: private fieldIni enkapsulasi yang sesungguhnya: data hanya bisa diubah lewat method resmi.
Catatan teknis: Class di JavaScript adalah syntactic sugar di atas prototype, bukan class seperti di Java atau C++. Di balik layar tetap memakai prototype chain. Juga, class declaration tidak di-hoisting seperti function: pakai sebelum definisi akan error. Selalu definisikan dulu, pakai kemudian.
Studi kasus: kasir OOP mini
Rangkai class dalam contoh yang utuh:
class Produk {
constructor(nama, harga) {
this.nama = nama;
this.harga = harga;
}
}
class Keranjang {
#items = [];
tambah(produk, jumlah = 1) {
this.#items.push({ produk, jumlah });
}
total() {
return this.#items.reduce(
(acc, i) => acc + i.produk.harga * i.jumlah, 0
);
}
struk() {
return this.#items.map(i =>
`${i.produk.nama} x${i.jumlah} = Rp${i.produk.harga * i.jumlah}`
).join("
") + "
Total: Rp" + this.total();
}
}
let k = new Keranjang();
k.tambah(new Produk("Kopi", 15000), 2);
k.tambah(new Produk("Roti", 8000));
console.log(k.struk());Keranjang menyembunyikan #items dan hanya mengekspos method resmi. Mau tambah diskon? Tambah method di class Keranjang tanpa mengubah kode pemakainya. Itulah nilai OOP: perubahan lokal, efek terkendali.
Kesimpulan
Class merapikan pembuatan banyak object sejenis, extends untuk hierarki, # untuk privasi. Untuk aplikasi kecil, object literal dan factory function sering cukup. Pakai class saat polanya memang butuh cetakan berulang atau hierarki yang jelas.