Soal 1Setelah class Coupon {}, apa yang terjadi kalau kamu memanggil Coupon("SPRING") tanpa new?
Dasar class — Mendefinisikan Class dan Membuat Instance
Class dipakai untuk membuat banyak object dengan bentuk yang sama. Membahas cara membuat instance dengan constructor dan new, method yang memakai this, dan kapan object literal sudah cukup.
Member, produk, kupon: data yang punya field yang sama dan dipakai untuk perhitungan yang sama muncul berkali-kali di dalam aplikasi. Kalau setiap data kamu tulis sebagai object literal, field dan rumus perhitungannya ikut tersalin sebanyak jumlah datanya.
Artikel ini membahas class, yang menyatukan bentuk data dan kode pengolahnya di satu tempat, serta cara membuat object darinya satu per satu dengan new.
Menentukan Bentuk Data di Satu Tempat — class dan new
Ambil contoh dua jenis kupon diskon. Kalau { code: "WELCOME", discount: 500 } ditulis ulang untuk setiap kupon, lalu di salah satunya kamu salah ketik menjadi discont, kode tetap berjalan tanpa error, dan hanya value diskon kupon itu yang menjadi undefined. Nama key-nya ditulis di setiap kupon, jadi kamu harus mencari salah ketik itu di antara semuanya.
Class (sintaks untuk mendefinisikan jenis object yang dibuat dengan new) ditulis sebagai class Coupon { ... }, dan di dalamnya kamu menaruh constructor (bagian yang dipanggil oleh new) tanpa keyword function.
Di dalam constructor, this adalah instance baru (object yang dibuat dari class), dan new mengembalikan instance itu walaupun tidak ada return.
// Definisikan bentuk kupon di satu tempat dengan class
class Coupon {
constructor(code, discount) {
this.code = code; // Kiri: code milik instance. Kanan: argument yang diterima
this.discount = discount;
}
}
// Buat kupon satu per satu dengan new
const welcome = new Coupon("WELCOME", 500);
const summer = new Coupon("SUMMER", 1000);
console.log(welcome.code); // WELCOME
console.log(summer.discount); // 1000
console.log(welcome instanceof Coupon); // true
// Kalau dipanggil tanpa new, error dilempar
// Coupon("SPRING", 300); // TypeError
this di dalam constructor. Tanpa new, error dilempar sebelum masuk ke constructor.Nama key hanya ditulis di satu tempat, yaitu di dalam constructor, jadi salah ketik seperti discont cukup diperbaiki di satu tempat itu. Di kolom kanan, console menampilkan TypeError: Class constructor Coupon cannot be invoked without 'new'.
Menghitung dengan Value Milik Instance — Method dan this
Kalau rumus harga setelah diskon, total - welcome.discount, kamu tulis di halaman keranjang dan juga di halaman konfirmasi pesanan, setiap kali aturan harganya berubah ada dua tempat yang harus diperbaiki. Walaupun rumus itu dipindahkan ke sebuah function, field-nya tetap ada di dalam class, sedangkan perhitungannya ada di luar.
Method (function milik sebuah object yang dipanggil dengan titik, seperti welcome.apply(3000)) ditulis di dalam kurung kurawal class sebagai apply(total) { ... }, juga tanpa keyword function. Di dalam method, this merujuk ke instance yang ditulis di kiri titik, dan this.discount membaca value-nya pada saat method dipanggil.
class Coupon {
constructor(code, discount) {
this.code = code;
this.discount = discount;
}
// Kurangi total dengan diskon kupon ini, lalu kembalikan hasilnya
apply(total) {
return total - this.discount; // this adalah instance di kiri titik
}
}
// Buat dua jenis kupon
const welcome = new Coupon("WELCOME", 500);
const summer = new Coupon("SUMMER", 1000);
// apply yang sama memberi hasil berbeda, tergantung instance di kiri titik
console.log(welcome.apply(3000)); // 2500
console.log(summer.apply(3000)); // 2000
this adalah variabel yang ditulis di kiri apply. Walaupun argument-nya sama, hasilnya berbeda kalau this-nya berbeda.- Argument
code/discount— hanya bisa dipakai di dalam kurung kurawal ini this.discount = discount— menyimpan value di instance
this.discount— membaca value yang disimpan di instancetotal - discount— namanya tidak terlihat, jadiReferenceError
discount tidak terlihat di luar kurung kurawal constructor. apply membaca value yang disimpan di this.Kalau kamu lupa menulis this. di dalam apply dan menulis total - discount, JavaScript mencari nama discount mulai dari kurung kurawal paling dalam ke arah luar. Jadi hasilnya bergantung pada ada atau tidaknya variabel dengan nama yang sama di luar class.
Lupa this. Tidak Selalu Menimbulkan Error
Kalau di luar class ada variabel dengan nama yang sama, misalnya const discount = 300;, total - discount yang lupa diberi this. tidak melempar ReferenceError. Kode itu diam-diam memakai 300 tersebut. Kalau hasilnya selalu sama, kupon apa pun yang dipakai, periksa apakah ada this. yang terlupa.
Setiap Instance Menyimpan Value Sendiri — Beberapa Instance
Setiap kali sebuah kupon dipakai, sisa kuotanya berkurang satu. Kalau sisa kuota disimpan di luar class dalam object seperti { WELCOME: 3, SUMMER: 3 }, setiap halaman yang memakai kupon butuh kode sendiri untuk mencari kuota berdasarkan code lalu menulis kembali value yang sudah dikurangi.
Di dalam method, kamu juga bisa meng-assign value ke property this, seperti this.remaining = this.remaining - 1. Sisi kanan membaca kuota saat ini, lalu hasilnya, yang sudah berkurang satu, ditulis kembali ke remaining milik instance yang sama. Kuotanya dimulai dari 3 yang kamu berikan ke new, lalu berkurang satu setiap kali method dipanggil.
class Coupon {
constructor(code, remaining) {
this.code = code;
this.remaining = remaining; // Sisa berapa kali bisa dipakai
}
// Kurangi kuota instance di kiri titik sebanyak satu
use() {
this.remaining = this.remaining - 1;
}
}
// Buat dua kupon dengan kuota yang sama, lalu pakai dengan jumlah berbeda
const welcome = new Coupon("WELCOME", 3);
const summer = new Coupon("SUMMER", 3);
welcome.use();
welcome.use();
summer.use();
console.log(welcome.remaining); // 1
console.log(summer.remaining); // 2
Instance tidak hanya bisa disimpan di variabel, tapi juga di array. Saat kamu memanggil method pada sebuah element, seperti coupons[0].use(), this merujuk ke element itu. Berapa pun jumlah kuponnya, kode yang mengurangi kuota tetap hanya satu baris di dalam use().
Memilih Berdasarkan Jumlah Data — class atau Object Literal
Untuk data yang hanya dipakai sekali, seperti pengaturan tampilan sebuah halaman, cukup tulis { ... } di tempat itu. Tapi untuk data seperti kupon, yang dibuat berkali-kali dengan bentuk dan perhitungan yang sama, cara ini membuat isi perhitungannya pun ikut tersalin ke setiap data.
Object literal juga bisa punya method: tulis apply(total) { ... } di samping pasangan key dan value, dan this di dalamnya merujuk ke object itu. Bedanya dengan class ada di tempat body method ditulis, dan perbedaan itu terlihat di hasil Object.keys.
// class: body ditulis sekali, di dalam definisi
class Coupon {
constructor(code, discount) {
this.code = code;
this.discount = discount;
}
apply(total) { return total - this.discount; }
}
const welcome = new Coupon("WELCOME", 500);
// Literal: body ditulis ulang untuk setiap data
const summer = {
code: "SUMMER",
discount: 1000,
apply(total) { return total - this.discount; },
};
// Key yang dimiliki berbeda
console.log(Object.keys(welcome).join(", ")); // code, discount
console.log(Object.keys(summer).join(", ")); // code, discount, apply
Walaupun letak body-nya berbeda, welcome.apply(3000) dipanggil dengan cara yang sama persis seperti summer.apply(3000), jadi kode pemanggilnya tidak berubah. Bagaimana instance bisa memanggil method yang body-nya ada di class akan dibahas di artikel tentang prototype. Tabel di bawah membandingkan kedua cara tersebut.
| Aspek | Object literal | class |
|---|---|---|
| Object yang dibuat | Hanya yang ditulis di { } | Satu per new |
| Body method | Disalin ke setiap data | Sekali di class |
| Key di Object.keys | code, discount, apply | code, discount |
| instanceof Coupon | false | true |
| Cocok untuk | Config sekali pakai | Banyak data, logika sama |
Jangan Beri Koma Setelah Method di Class
Saat mengubah literal menjadi class, kalau koma setelah method masih tertinggal, seperti apply(total) { ... },, muncul SyntaxError: Unexpected token ',' dan tidak ada satu baris kode pun yang berjalan. Di dalam kurung kurawal class, method cukup ditulis berurutan tanpa pemisah.
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Di luar class ada variabel discount bernilai 300. Apa yang dikembalikan welcome.apply(3000) kalau this. terlupa?
Soal 3Apa hasil Object.keys untuk instance dari class yang punya constructor(code, discount) dan apply?