Select Page

Saat ini saya ingin membahas tentang prototype dan rantai prototype (prototype chain) pada Javascript. Kita biasa mendenger inheritance dengan class. Ini adalah inheritance yang biasa kita lakukan karena itu yang diajarkan ketika sekolah atau kuliah. Tetapi JS tidak menggunakan class untuk inheritance. JS menggunakan function dan prototype. Ketika meng-create object kita memanggil function tersebut dengan new. Dan function tersebut akan menggunakan prototype sebagai this value.

log = console.log.bind(console);

userPrototype = {meta: 'userPrototype'}

function User(name){
this.name = name;
}

User.prototype = userPrototype;

user = new User('Budi');

log(user) //{meta: "userPrototype", name: "Budi"}

Pada code diatas, kita meng-create sebuah object userPrototype. Lalu setelah itu Kita mendefenisikan sebuah function User yang property prototypenya kita assign dengan userPrototype. Lalu kita create sebuah object baru, dengan memanggil function User menggunakan new. Function yang dipanggil dengan new juga biasa disebut sebagai constructor. Jadi pada code diatas function User juga disebut sebagai constructor. Class di ES6 sebenarnya adalah sytactic sugar dari prototypical inheritance. Jadi class di ES6 itu sebenarnya adalah function. Yang artinya class juga memiliki prototye.

log = console.log.bind(console);
class Foo{
}
log(typeof Foo === 'function'); //true
log(Foo.prototype !== undefined); //true

Oleh karena itu, setiap function (yang digunakan sebagai constructor), memiliki prototype. Dan bisa diakses melalui property prototype. Berbeda dengan prototype pada function/constructor, prototype dari suatu object bisa kita dapatkan dengan mengakses property __proto__ atau di ES6 dengan menggunakan Object.getPrototypeOf. Kode berikut membuktikan prototype dari user adalah userPrototype.

log = console.log.bind(console);
userPrototype = {meta: 'userPrototype'}
function User(name){
this.name = name;
}
User.prototype = userPrototype;
user = new User('Budi');

log(Object.getPrototypeOf(user) === userPrototype) //true

Bila kita mengakses property dari suatu object, maka pertama kali JS akan mencoba mencari property tsb pada object itu sendiri, dan jika tidak ditemukan maka JS akan mencoba mencari property tersebut dari prototype object tsb dan jika property itu tidak ditemukan juga, JS akan mencari property tersebut dari prototypenya prototype object tsb. Ini disebut dengan prototype chain.

JS Prototype Chain

Dari gambar prototype chain di atas, kita bisa melihat bahwa root prototype dari suatu object adalah Object.prototype. Kode berikut membuktikan bahwa prototype dari user adalah userPrototype. Dan prototype dari userPrototype adalah Object.prototype. Dan yang terakhir, karena Object.prototype ini adalah root prototype maka prototypenya adalah null.

log = console.log.bind(console);
userPrototype = {meta: 'userPrototype'}
function User(name){
this.name = name;
}
User.prototype = userPrototype;
user = new User('Budi');

log(Object.getPrototypeOf(user) === userPrototype) //true
log(Object.getPrototypeOf(userPrototype) === Object.prototype) //true
log(Object.getPrototypeOf(Object.prototype) === null) //true

Jadi ketika kita mengakses user.toString(), maka property itu akan dicoba dicari pada object user, dan karena tidak ditemukan maka property itu akan dicoba dicari pada prototype dari object user yaitu userPrototype dan karena tidak ditemukan juga maka prototype dari userPrototype yang akan dicari yaitu Object.prototype.

JS Prototype Chain

Jadi bisa disimpulkan bahwa function toString pada user itu sebenarnya berada pada root prototype atau Object.prototype. Kode berikut membuktikannya.

log = console.log.bind(console);
userPrototype = {meta: 'userPrototype'}
function User(name){
this.name = name;
}
User.prototype = userPrototype;
user = new User('Budi');

log(user.toString === Object.prototype.toString) //true

Oleh karena itu apabila kita mengakses property dari suatu object dan setelah JS mencoba mencari property tersebut melewati prototype chain sampai dengan Object.prototype, dan property itu tidak juga ditemukan, berarti dapat disimpulkan property tersebut undefined dan JS akan mengembalikan undefined.

log = console.log.bind(console);
userPrototype = {meta: 'userPrototype'}
function User(name){
this.name = name;
}
User.prototype = userPrototype;
user = new User('Budi');

log(user.foo === undefined) //true

Demo: http://jsbin.com/tawabuq/edit?js

OK, sekian dulu post dari saya. Dan sebagai penutup saya ingin menambahkan ketika bermain dengan JS, mengetahui cara kerja dari prototype chain ini sangat penting. Kalau tidak mungkin kita bisa kebingungan dibuatnya. Bagaimana pendapat dari teman-teman, silahkan komen ya 🙂

Credits: http://bittersweetryan.github.io/art-of-javascript/images/property-lookup.png

%d bloggers like this: