Soal 1Parcel punya static count = 0;. Apa yang kamu dapat kalau membaca first.count dari instance first?
Instance Member dan static — Value dan Method Milik Class
static menaruh value dan method di class itu sendiri. Membahas counter dengan static field, factory method yang membuat instance dari JSON, konstanta bersama, dan kapan memakai instance member.
Untuk memberi nomor 1, 2, 3 pada paket sesuai urutan pembuatannya, kamu perlu mencatat berapa paket yang sudah dibuat. Penerima setiap paket berbeda, tapi jumlah paket yang sudah dibuat dan batas berat cukup ada satu, dipakai bersama oleh semua paket.
Artikel ini membahas static, yang menaruh value dan method di class itu sendiri, bukan di instance-nya.
Menghitung Jumlah Paket — static Field
Kalau kamu menulis class field count = 0;, menambahnya dengan this.count += 1 di constructor, lalu memakainya sebagai nomor paket, semua paket mendapat nomor 1, karena field diisi ulang dari 0 setiap kali new dipanggil.
Static field (property yang dideklarasikan di dalam class dengan keyword static; hanya ada satu, di class itu sendiri) dibaca dan ditulis lewat nama class, seperti Parcel.count.
Sebaliknya, property yang dimiliki setiap instance, seperti this.number, dan method yang ditulis tanpa static disebut instance member.
class Parcel {
// Jumlah paket yang sudah dibuat, disimpan sekali di class
static count = 0;
constructor(recipient) {
Parcel.count += 1; // Tambah count milik class sebanyak satu
this.number = Parcel.count; // Pakai count saat ini sebagai nomor paket
this.recipient = recipient;
}
}
// Buat dua paket
const first = new Parcel("Budi");
const second = new Parcel("Siti");
console.log(first.number, second.number); // 1 2
console.log(Parcel.count); // 2
console.log(first.count); // undefined
static count— 1 setelahnewpertama, 2 setelahnewkedua- Dibaca dan ditulis sebagai
Parcel.count
number— 1 (count saat dibuat)recipient— "Budi"- Tidak ada
count—first.countbernilaiundefined
number— 2 (count saat dibuat)recipient— "Siti"
count hanya ada satu, di kotak class, dan tidak ada di kotak instance. Kalau dibaca dari instance, hasilnya undefined.Setiap pemanggilan new menambah count yang sama di kotak class sebanyak satu, lalu menyalin value-nya saat itu ke number milik instance baru. Walaupun count kemudian naik menjadi 2, first.number tetap 1, yaitu value yang didapatnya saat dibuat.
Membuat Paket dari JSON — static Method
Saat memuat paket yang sudah disimpan, yang kamu dapat adalah string JSON berisi penerima dan berat. Kalau setiap halaman yang memuat paket punya JSON.parse dan new Parcel(...) sendiri, perubahan nama key di JSON berarti semua halaman itu harus diperbaiki.
Masalahnya, saat membuat paket dari JSON, belum ada instance yang bisa dipakai untuk memanggil method. Static method (method yang didefinisikan dengan static dan dipanggil lewat nama class tanpa membuat instance) bisa dipanggil sebagai Parcel.fromJSON(text). Static method seperti fromJSON, yang membuat lalu mengembalikan instance, disebut factory method.
class Parcel {
constructor(recipient, weightKg) {
this.recipient = recipient;
this.weightKg = weightKg;
}
label() {
return `${this.recipient} (${this.weightKg} kg)`;
}
// Terima string JSON, lalu buat dan kembalikan instance Parcel
static fromJSON(text) {
const data = JSON.parse(text);
return new Parcel(data.recipient, data.weightKg);
}
}
const text = '{"recipient":"Budi","weightKg":2}';
const parcel = Parcel.fromJSON(text); // Dipanggil lewat nama class
console.log(parcel.label()); // Budi (2 kg)
JSON.parse menghasilkan object biasa yang punya property tapi tidak punya method. Baru setelah melewati new, object itu menjadi instance yang bisa memanggil label().Baris terakhir fromJSON adalah new Parcel(...), jadi body constructor tetap berjalan seperti biasa. Kalau kamu menaruh pengecekan dengan throw di constructor, paket yang dimuat kembali dari JSON juga melewati pengecekan yang sama dengan paket yang diinput di layar.
fromJSON Tidak Bisa Dipanggil dari Instance
Kalau dipanggil dari instance, seperti parcel.fromJSON(text), kode melempar TypeError: parcel.fromJSON is not a function. Berbeda dengan label(), static method hanya bisa dipanggil lewat nama class. Cara kerjanya dibahas di artikel tentang prototype.
Batas yang Sama untuk Semua Paket — static Constant
Batas berat 30 kg dipakai di dua tempat: di keterangan formulir input, yang tampil sebelum ada paket apa pun, dan di perhitungan sisa kapasitas setiap paket. Kalau batas itu ditaruh di field instance, kamu harus membuat paket tanpa penerima dan tanpa berat hanya untuk menampilkan keterangan di formulir.
Static constant (static field berisi value yang tidak pernah berubah selama program berjalan) diberi nama dengan huruf kapital semua, dan setiap kata dipisah dengan underscore, seperti static MAX_WEIGHT_KG = 30;. Baik dari luar class maupun dari dalam method, kamu membacanya lewat nama class: Parcel.MAX_WEIGHT_KG.
class Parcel {
// Batas yang berlaku untuk semua paket disimpan sekali di class dengan static
static MAX_WEIGHT_KG = 30;
constructor(weightKg) {
this.weightKg = weightKg;
}
// Berapa kg lagi yang masih muat sampai batas
remainingKg() {
return Parcel.MAX_WEIGHT_KG - this.weightKg;
// Kalau ditulis this.MAX_WEIGHT_KG - this.weightKg, hasilnya NaN
}
}
// Bisa dibaca bahkan sebelum ada instance
console.log(`Maksimal ${Parcel.MAX_WEIGHT_KG} kg per paket`); // Maksimal 30 kg per paket
const parcel = new Parcel(12);
console.log(parcel.remainingKg()); // 18
Kolom kanan berakhir dengan NaN karena this di dalam method merujuk ke instance, sedangkan static constant tidak ada di instance. undefined - 12 tidak melempar error, jadi kamu baru sadar saat sisa berat yang ditampilkan terlihat aneh.
Nama Berhuruf Kapital Tetap Bisa Di-assign Ulang
Nama berhuruf kapital hanyalah konvensi yang berarti "jangan diubah"; kalau kamu meng-assign Parcel.MAX_WEIGHT_KG = 50;, value-nya tetap berubah. Kalau kamu hanya mendefinisikan getter, seperti static get MAX_WEIGHT_KG() { return 30; }, assignment ke nama itu melempar TypeError (getter dibahas di artikel berikutnya).
Menentukan Tempat Menyimpan Value — static atau Instance
Setelah mengenal static, mungkin terasa praktis kalau value seperti penerima juga ditaruh di class supaya bisa dibaca dari satu tempat, Parcel.recipient. Dalam tes singkat yang hanya membuat satu paket, penerima yang tampil sama saja, baik disimpan di static maupun di this, jadi kamu tidak akan melihat bedanya.
Tentukan tempat menyimpan sebuah value berdasarkan apakah value itu berbeda untuk setiap data. Value yang disimpan di this ada secara terpisah di setiap instance yang dibuat dengan new, sedangkan value static hanya ada satu di class, berapa pun paket yang kamu buat.
// Penerima disimpan di static
class SharedParcel {
static recipient = "";
constructor(recipient) { SharedParcel.recipient = recipient; }
label() { return `Kepada: ${SharedParcel.recipient}`; }
}
// Penerima disimpan di instance
class Parcel {
constructor(recipient) { this.recipient = recipient; }
label() { return `Kepada: ${this.recipient}`; }
}
const sharedFirst = new SharedParcel("Budi");
new SharedParcel("Siti");
console.log(sharedFirst.label()); // Kepada: Siti
const first = new Parcel("Budi");
new Parcel("Siti");
console.log(first.label()); // Kepada: Budi
sharedFirst tidak punya penerima sendiri, dan label() membaca SharedParcel.recipient sesuai value-nya saat dipanggil, jadi yang tampil adalah "Siti", value terakhir yang di-assign. Tabel di bawah merangkum member paket di artikel ini: cara menulis dan cara memakai masing-masing.
| Yang disimpan | Cara menulis dan memakai | Contoh di sini |
|---|---|---|
| Value per data | Di this, baca dari instance | number / recipient / weightKg |
| Method untuk value per data | Tanpa static, panggil dari instance | label() / remainingKg() |
| Satu value untuk semua | Dengan static, baca lewat nama class | count / MAX_WEIGHT_KG |
| Logika tanpa instance | Dengan static, panggil lewat nama class | fromJSON(text) |
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Apa yang terjadi kalau kamu memanggil static method dari instance parcel, seperti parcel.fromJSON(text)?
Soal 3Sebuah class menyimpan penerima di static field. Kalau kamu membuat paket untuk "Budi" lalu paket untuk "Siti", penerima apa yang ditampilkan label() milik paket pertama?