Setiap object di JavaScript punya prototype: object lain tempat dia ikut mencari properti yang gak dia punya sendiri. Kalau sebuah properti gak ketemu di object itu, JavaScript mencarinya di prototype-nya, lalu di prototype milik prototype itu, terus naik sampai ujung. Jalur pencarian ini disebut prototype chain.
🧪 Tebakan cepat: object
kucingdi bawah gak punya methodtoString, tapikucing.toString()tetap jalan. Method itu datang dari mana? Tebak dulu, jawabannya ada di bagian "Mencari naik ke prototype".
Mencari naik ke prototype
function Hewan(nama) {
this.nama = nama
}
Hewan.prototype.sapa = function () {
return 'Saya ' + this.nama
}
const kucing = new Hewan('Kitty')
kucing.nama // 'Kitty', milik kucing sendiri
kucing.sapa() // 'Saya Kitty', ketemu di Hewan.prototype
kucing.toString() // '[object Object]', ketemu di Object.prototype
kucing.terbang // undefined, gak ketemu di mana pun
function Hewan(nama)adalah constructor function: fungsi biasa yang dipanggil dengannewbuat bikin object.new Hewan('Kitty')bikin object baru. Di dalam fungsinya,thismenunjuk object baru itu, jadithis.nama = namamemberikucingpropertinamamiliknya sendiri.Hewan.prototypeadalah prototype buat semua object hasilnew Hewan(...). Method yang ditaruh di situ, kayaksapa, dipakai bareng oleh semuanya.kucing.sapa():kucinggak punyasapa, jadi JavaScript naik keHewan.prototypedan menemukannya di sana.this.namadi dalamnya tetap milikkucing.
Rantainya: kucing → Hewan.prototype → Object.prototype → null. Object.prototype ada di ujung hampir semua rantai, dan di situlah toString tinggal. Itu jawaban tebakan. Kalau sampai null masih gak ketemu, hasilnya undefined.
Demo di bawah memakai class, cara menulis yang lebih ringkas buat pola yang sama (dibahas di materi berikutnya). Rantainya dog → Dog.prototype → Animal.prototype → Object.prototype → null.
Method di prototype, data di constructor
const a = new Hewan('Kitty')
const b = new Hewan('Mochi')
a.sapa === b.sapa // true, satu fungsi yang sama
a.__proto__ === Hewan.prototype // true
- Data yang beda di tiap object (
nama) ditulis di dalam constructor lewatthis. - Method ditulis sekali di prototype, di luar constructor:
Hewan.prototype.sapa = function () { ... }. Semua object memakai fungsi yang sama, jadi gak ada salinan di tiap object. - Pakai
function, bukan arrow function, buat method di prototype. Cumafunctionyangthis-nya menunjuk object yang memanggilnya. - Link dari object ke prototype-nya tersimpan di properti tersembunyi
__proto__. Cara yang dianjurkan buat membacanya:Object.getPrototypeOf(a).
⚠️ Jebakan yang sering ketemu
- Arrow function sebagai method.
Hewan.prototype.sapa = () => 'Saya ' + this.namagak bisa membacanamamilik object-nya, karenathisdi arrow function bukan object itu. - Lupa
new.const k = Hewan('Kitty')tanpanewgak bikin object baru, jadikgak berisi object. - Mengubah
Object.prototype. Hampir semua object ikut kena, jadi bug-nya bisa muncul di mana saja. Jangan tambah apa pun ke sana.
TL;DR: Tiap object punya prototype, dan properti yang gak ketemu dicari naik lewat prototype chain sampai null. Constructor function dipanggil dengan new, menyimpan data lewat this, dan method-nya ditaruh sekali di NamaFungsi.prototype pakai function. Link ke prototype tersimpan di __proto__, dan Object.prototype di ujung rantai menyediakan method seperti toString.