Memahami Javascript sebagai Prototype-based Language

Prototype adalah konsep fundamental yang harus diketahui oleh Programmer yang ingin belajar Javascript secara mendalam

Wahyudi Wibowo
Apr 29, 2017 · 6 min read
Image for post
Image for post

Javascript adalah bahasa yang menantang untuk dipelajari. Karena konsep yang ditawarkan berbeda dari bahasa pemrograman interpreter kebanyakan seperti PHP, Python, atau Ruby. Javascript adalah bahasa yang asynchronous, non-blocking, dan prototype-based. Di artikel ini, kita akan membedah Javascript dari style yang digunakan yaitu Prototype-based Language.

Objects, Objects, Objects Everywhere!

- Douglas Crockford

Pada Javascript, object memegang peranan yang sangat penting. Bahkan function diperlakukan sebagai First Class Objects yang artinya sebuah function dapat disimpan dalam data structure, dijadikan argumen atau dijadikan return value dari function lain. Mari kita lihat contoh kode di bawah ini :

Jika kita jalankan di terminal maka hasilnya

Image for post
Image for post

Untuk lebih jelasnya, mari kita replikasi contoh kode di atas ke dalam chrome console

Image for post
Image for post

Poinnya adalah, sebuah function dianggap “belum aktif” jika ditulis tanpa (). Belum aktif disini artinya function tidak akan langsung dieksekusi oleh program dan dapat diperlakukan seperti object biasa. Di Javascript, kita akan sering menemukan object dengan property yang memiliki value berupa function. Property ini disebut dengan method.

Selain itu, karena Javascript tidak mengenal konsep class, maka inheritance atau pewarisan dari satu object ke object lain menggunakan sebuah property khusus yang dimiliki oleh semua object yaitu prototype.

Inheritance via Prototype Chain

Konsep inheritance via prototype chain biasanya membuat bingung programmer yang datang dari background bahasa pemrograman berbasis class. Karena memang di Javascript tidak dikenal konsep class. Sekedar informasi, pada ES6 memang dikenalkan sintaks class, namun sintaks itu hanyalah syntatic sugar dari prototype itu sendiri. Seperti yang telah dibahas sebelumnya, object mewarisi property object lainnya melalui prototype chain.

Next, kita akan membahas bagaimana implementasi inheritance via prototype chain pada regular object dan constructor function.

__proto__ Property dan Object.create

Sebelum kita masuk ke pembahasan __proto__ property pada object, saya perlu mengingatkan bahwa mengakses__proto__ secara langsung sangat tidak disarankan karena dampaknya yang signifikan pada performance. Contoh dibawah ini bertujuan untuk memudahkan penjelasan tentang inheritance melalui __proto__ object. Namun jangan mengimplementasikannya di production level.

Kita akan coba menjalankan kode tersebut di chrome console

Image for post
Image for post

Hanya dengan meng-assign object bird ke dalam property __proto__ yang dimiliki object eagle, secara otomatis object eagle mewarisi semua property dari object bird. Mudah bukan ? Kita coba dengan 1 contoh lagi :

Image for post
Image for post

Seperti yang kita lihat diatas, meng-assign object X ke dalam __proto__ object Y akan membuat object Y mewarisi seluruh property dari object X. Begitu pula dengan object Z yang mewarisi seluruh property dari object Y yang sebelumnya mewarisi property dari object X. Inilah cara kerja dari prototype chaining. Andaikan kita mengakses sebuah property dari object misalnyabird.food, maka Javascript akan mencari property food pada object bird. Jika tidak ditemukan, maka Javascript akan menelusuri prototype yang mengarah ke parent dari object tersebut sampai property food ditemukan. Begitu seterusnya sampai akhirnya Javascript mengembalikan value dari property food atauundefined jika property food benar-benar tidak ditemukan.

Tadi sempat kita bahas bahwa inheritance melalui __proto__ tidak disarankan. Javascript telah menyediakan alternatif yang dapat kita gunakan yaitu Object.create. Mari kita refactor contoh-contoh diatas dengan menggunakan Object.create. Note: Object.create adalah fitur yang baru ada sejak ES5 dan tidak bisa berjalan di browser lama seperti IE8.

Jika 2 scripts ini dijalankan maka hasilnya akan sama dengan contoh yang memakai __proto__. Dan yang perlu dicatat, perubahan state yang terjadi di parent menyebabkan state yang ada di child berubah, sementara perubahan state di child tidak berpengaruh pada parent. Berikut contohnya:

dan jika kita jalankan di terminal

Image for post
Image for post

Selanjutnya kita akan membahas inheritance pada constructor function.

Constructor Functions

Metode inheritance via constructor function ini adalah metode yang cukup populer alias sering digunakan oleh para programmer Javascript. Caranya adalah dengan membuat sebuah function yang menjadi constructor dari object. Object yang diturunkan dari constructor function disebut dengan instance. Untuk lebih jelasnya mari kita lihat implementasi constructor function di bawah ini :

Jika kita jalankan di terminal

Image for post
Image for post

Function memiliki sebuah property khusus yang bernama prototype. Apa bedanya dengan property__proto__ yang telah kita bahas tadi ? Nah disinilah poin yang (lagi-lagi) membuat bingung programmer dalam memahami Javascript. Perlu dicatat bahwa tidak seperti regular object yang hanya memiliki property __proto__, function memiliki 2 macam prototype property : __proto__ dan prototype. Property__proto__ pada function tidak sama dengan propertyprototypenya.

Image for post
Image for post

Lalu apakah property prototype yang terdapat pada function tersebut? Secara sederhana, semua function di Javascript memiliki property prototype. Fungsi utama dari property prototype ini adalah sebagai shared resource yang digunakan oleh semua instance dari sebuah constructor function, baik yang ada sekarang maupun yang akan dipanggil di masa depan. Semua object yang dibuat dengan menggunakan new akan mewarisi seluruh property yang ada di prototype ini. Bagaimana cara kerjanya akan kita bahas di bawah.

Lalu apa bedanya jika kita memakaiprototype? Bukankah sama saja hasilnya jika kita menuliskanBird.prototype.color = 'brown' dengan this.color = 'Brown’ pada constructor Bird ? Secara fungsional memang sama, namun penggunaan prototype memiliki kelebihan yaitu optimasi memory. Mari kita lihat penjelasan kode di bawah ini :

Note : untuk menandai bahwa function tersebut adalah constructor function, huruf pertama dari nama function tersebut diawali dengan huruf kapital.

Sekarang kita coba jalankan kode di atas

Image for post
Image for post

Sekilas nampak sama karena baik foo.c() dan bar.c() sama-sama mengembalikan nilai 3. Akan tetapi ketika kita menginspeksi instance foo dan bar dengan console.log terlihat perbedaan bahwa instance dari function Foo terdiri dari 3 object, sementara instance dari function Bar hanya terdiri dari 2 object saja. Berarti jika ada 100 instance dari masing-masing Foo dan Bar, maka Foo akan menghabiskan 300 slot memory sementara Bar hanya 200. Padahal secara fungsional, keduanya memiliki hasil yang sama. Inilah yang dimaksud dengan optimasi memory dengan menggunakan prototype.

Bagaimana itu bisa terjadi sebenarnya tidak lepas dari cara kerja dari keyword newyaitu :

  1. new akan membuat sebuah object baru, dan semua this yang ada di constructor akan di-bind ke object yang baru.
  2. Property prototype pada constructor akan di-set ke property __proto__ pada object yang baru dibuat tadi.

Poin 1 sudah dibuktikan dengan kode yang ada di atas, sekarang mari kita buktikan poin 2

Image for post
Image for post

Bingo! bisa kita lihat ternyata Bar.prototype sama dengan (new Bar()).__proto__ yang artinya property prototype yang ada pada constructor function akan di-assign ke dalam __proto__ instance yang dipanggil dengan new. Jika kita bedah object bar (yang dibuat dari new Bar()), terlihat bahwa function c() berada di property __proto__ object bar.

Image for post
Image for post

Kesimpulan

Sekarang kita sudah memahami bahwa ada 2 cara untuk melakukan inheritance di Javascript yaitu dengan Object.create dan constructor. Di pembahasan terakhir ini, mari kita bandingkan implementasi inheritance dengan menggunakan Object.create dan constructor.

Dengan constructor :

Dengan Object.create :

Dan jika dijalankan, 2 script di atas memberikan hasil yang sama :

Image for post
Image for post

Jadi menurut teman-teman, manakah yang lebih mudah dipahami, inheritance dengan Object.create atau constructor ? Tinggalkan komentar di bawah ya 😊

Terimakasih telah membaca artikel ini. Apabila anda menyukainya klik ❤️ dan share serta follow medium, facebook, atau twitter Koding Kala Weekend untuk mendapat info tentang artikel terbaru kami.

Koding Kala Weekend

Belajar pemrograman di akhir pekan

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store