Setiap object di JavaScript terhubung ke object lain melalui tautan internal yang disebut prototipe, dan pencarian properti yang tidak ditemukan di object itu sendiri dilanjutkan ke sana. Mekanisme ini disebut delegasi, yaitu penerusan kebutuhan yang tidak bisa dipenuhi satu object kepada object lain di atasnya. Topik ini menelusuri delegasi pada rantai prototipe yang berujung di null, lalu memisahkan dua istilah yang mudah tertukar, yaitu __proto__ dan prototype. Bagian akhirnya menunjukkan cara lama berbagi metode lewat fungsi konstruktor dan menutup dengan Object.create yang ringkas. Semua contoh berupa berkas JavaScript utuh yang dijalankan dengan Node.js.
Delegasi pencarian properti#
Ketika sebuah properti dibaca, JavaScript memeriksa object itu sendiri terlebih dahulu. Bila nilainya tidak ada, pencarian berlanjut ke prototipenya, lalu ke prototipe dari prototipe itu, sampai nilai ditemukan atau rantainya habis. Properti yang ditulis langsung pada object disebut properti sendiri, sedangkan properti yang ditemukan di prototipe tetap bisa dipakai seolah-olah milik object tersebut. Berkas berikut membuat dua object patroli yang mewarisi data dan metode dari object induknya.
// Properti yang tidak ada di object dicari pada prototipenya.
const kendaraanDinas = {
roda: 4,
servisTahunan() {
return this.nomor + " dijadwalkan servis tahunan";
}
};
const mobilPatroli = {
__proto__: kendaraanDinas,
nomor: "D 9001 AB"
};
const motorPatroli = {
__proto__: kendaraanDinas,
nomor: "D 9002 CD"
};
console.log(mobilPatroli.nomor);
console.log(mobilPatroli.roda);
console.log(mobilPatroli.servisTahunan());
console.log(motorPatroli.servisTahunan());D 9001 AB
4
D 9001 AB dijadwalkan servis tahunan
D 9002 CD dijadwalkan servis tahunannomor adalah properti sendiri masing-masing object, sedangkan roda tidak ada di kedua object itu sehingga dicari di kendaraanDinas dan menghasilkan 4. Metode servisTahunan juga ditemukan di prototipe, tetapi perhatikan this-nya. Pemanggilan lewat mobilPatroli menghasilkan nomor mobil, sedangkan pemanggilan lewat motorPatroli menghasilkan nomor motor, karena this tetap menunjuk object di depan titik. Satu salinan metode melayani dua object dengan data berbeda, dan itulah inti kegunaan delegasi.
Rantai prototipe berakhir di null#
Rantai pencarian itu punya ujung yang pasti. Object biasa mewarisi dari Object.prototype, yang berisi metode umum seperti toString, dan prototipe dari Object.prototype adalah null, tanda bahwa pencarian berhenti tanpa lanjutan. Fungsi Object.getPrototypeOf membaca prototipe sebuah object dengan cara yang didukung penuh standar, lebih disarankan daripada __proto__ yang lazim dianggap usang. Berkas berikut memeriksa rantai tersebut langkah demi langkah.
// Rantai prototipe berakhir pada null.
const kendaraanDinas = { roda: 4 };
const mobilPatroli = { __proto__: kendaraanDinas, nomor: "D 9001 AB" };
console.log(Object.getPrototypeOf(mobilPatroli) === kendaraanDinas);
console.log(Object.getPrototypeOf(kendaraanDinas) === Object.prototype);
console.log(Object.getPrototypeOf(Object.prototype));
console.log(mobilPatroli.toString === Object.prototype.toString);
console.log(mobilPatroli.tidakAda);true
true
null
true
undefinedTiga perbandingan pertama menunjukkan urutan rantai, mobilPatroli mewarisi kendaraanDinas, yang mewarisi Object.prototype, yang prototipenya null. Metode toString tidak ditulis di mana pun pada contoh ini, tetapi ditemukan di Object.prototype, sehingga mobilPatroli.toString bernilai sama dengan metode bawaan itu. Properti tidakAda tidak ditemukan di sepanjang rantai, dan hasil akhirnya undefined tanpa error. Diagram berikut merangkum rantai delegasi pada contoh di atas beserta arah pencariannya.
proto dan prototype#
Dua istilah ini terlihat serupa tetapi menunjuk hal yang berbeda. Properti prototype melekat pada fungsi dan berisi object yang menjadi prototipe bagi setiap object yang dibuat lewat new dari fungsi itu. Pada sisi object, __proto__ atau lebih resminya Object.getPrototypeOf membaca prototipe sebuah object yang sudah ada. Jadi prototype berada di sisi fungsi pembuat, sedangkan prototipe object adalah hasil pemasangan dari properti tersebut saat new berjalan.
// __proto__ adalah prototipe sebuah object, prototype adalah properti fungsi.
function Kendaraan(nomor) {
this.nomor = nomor;
}
Kendaraan.prototype.servis = function () {
return this.nomor + " servis terjadwal";
};
const mobil = new Kendaraan("D 9001 AB");
console.log(mobil.__proto__ === Kendaraan.prototype);
console.log(Object.getPrototypeOf(mobil) === Kendaraan.prototype);
console.log(Kendaraan.prototype.nomor);
console.log(mobil.servis());true
true
undefined
D 9001 AB servis terjadwalFungsi Kendaraan adalah fungsi konstruktor, yaitu fungsi yang dipanggil dengan new untuk membuat object. Prototipe object mobil memang Kendaraan.prototype, dibuktikan oleh dua perbandingan yang menghasilkan true. Properti nomor tidak ada di Kendaraan.prototype karena nilainya ditempel di dalam constructor pada setiap object hasil new, sehingga Kendaraan.prototype.nomor menghasilkan undefined. Metode servis tersedia karena ditulis pada prototype, dan setiap object hasil new Kendaraan mewarisinya.
Berbagi metode lewat prototype#
Sebelum sintaks class hadir, cara standar berbagi metode adalah menuliskannya pada prototype fungsi konstruktor. Pola ini patut dikenali karena masih banyak ditemui di kode lama, dan mekanismenya persis sama dengan yang dipakai kelas modern. Data ditempel di dalam constructor karena nilainya berbeda untuk setiap instansi, yaitu object hasil pemanggilan new, sedangkan metode ditulis satu kali di prototype karena perilakunya sama untuk semua.
// Metode pada prototype dibagi satu salinan untuk semua instansi.
function Buku(judul, tahun) {
this.judul = judul;
this.tahun = tahun;
}
Buku.prototype.usiaTahun = function (tahunKini) {
return tahunKini - this.tahun;
};
const bukuA = new Buku("Kamus Bahasa Indonesia", 2008);
const bukuB = new Buku("Ensiklopedia Sains", 2015);
console.log(bukuA.usiaTahun(2026));
console.log(bukuB.usiaTahun(2026));
console.log(bukuA.usiaTahun === bukuB.usiaTahun);
console.log(bukuA.judul === bukuB.judul);18
11
true
falsePerbandingan bukuA.usiaTahun === bukuB.usiaTahun menghasilkan true karena kedua instansi memakai satu fungsi yang sama di prototype, sedangkan judul milik masing-masing object sehingga perbandingannya false. Dengan seribu instansi, seribu salinan metode yang identik tidak ikut dibuat, cukup satu. Efisiensi ini salah satu alasan mekanisme prototype dipertahankan sampai sekarang.
Object.create ringkas#
Fungsi Object.create membuat object baru dengan prototipe pilihan dalam satu panggilan, tanpa perlu fungsi konstruktor. Argumennya adalah object yang menjadi prototipe, dan hasilnya adalah object kosong yang siap diisi properti sendiri. Bentuk ini ringkas untuk berbagi data dan metode di antara beberapa object sederhana.
// Object.create membuat object dengan prototipe pilihan.
const prototipeNota = {
ringkas() {
return this.tanggal + ": " + this.jumlah + " item";
}
};
const notaHariIni = Object.create(prototipeNota);
notaHariIni.tanggal = "2026-01-12";
notaHariIni.jumlah = 3;
console.log(notaHariIni.ringkas());
console.log(Object.getPrototypeOf(notaHariIni) === prototipeNota);2026-01-12: 3 item
trueObject notaHariIni tidak pernah menulis metode ringkas, tetapi pemanggilannya tetap berjalan karena prototipenya menyediakannya. Perbandingan terakhir memastikan prototipeNota memang menjadi prototipe object hasil Object.create. Untuk kebutuhan yang lebih besar, sintaks kelas membungkus mekanisme ini dalam tulisan yang lebih rapi.
Ringkasan#
- Pencarian properti berlanjut ke prototipe bila nilai tidak ditemukan di object itu sendiri, mekanisme yang disebut delegasi.
- Rantai prototipe berujung pada
null, denganObject.prototypesebagai pemberi metode umum di atasnya. prototypeadalah properti fungsi yang menjadi cetakan object buatannew, sedangkan__proto__danObject.getPrototypeOfmembaca prototipe object yang sudah ada.- Metode pada prototype dibagi satu salinan untuk semua instansi, dan
Object.createmembuat object baru dengan prototipe pilihan tanpa konstruktor.
Referensi#
- Inheritance and the prototype chain — MDN Web Docs — penjelasan rantai prototipe menurut dokumentasi resmi.
- Prototypal inheritance — The Modern JavaScript Tutorial — model delegasi prototipal dari dasar sampai rantainya.
- Object.create() — MDN Web Docs — dokumentasi pembuatan object dengan prototipe pilihan.