Belajar Memakai Inheritance Di JavaScript


Pada artikel Belajar Membuat Object Di JavaScript, saya membuat beberapa prototype dan object. Salah satunya adalah prototype untuk Faktur. Bagaimana bila seandainya saya ingin membuat sebuah turunannya dari Faktur seperti FakturJual? JavaScript tidak memiliki syntax khusus untuk inheritance, tapi hal ini dapat diakalin dengan menggunakan prototype. Sebagai contoh saya dapat membuat FakturJual yang baru dengan isi seperti berikut ini:

/** class FakturJual turunan dari Faktur **/
function FakturJual(nomor, tanggal, diskon, konsumen) {
    this.nomor = nomor;
    this.tanggal = tanggal;
    this.diskon = diskon;
    this.konsumen = konsumen;
}
FakturJual.prototype = new Faktur();

/** Contoh Penggunaan **/
var produkA = new Produk('Produk A', 120000, 10);
var produkB = new Produk('Produk B', 85000, 5);
var fakturJual = new FakturJual('FA-001', Date.now(), 10, 'Konsumen A');
console.log(fakturJual instanceof Faktur); // output: true
console.log(fakturJual instanceof FakturJual); // output: true

Karena saya memberi nilai prototype untuk FakturJual berupa sebuah instance dari Faktur, maka seluruh yang dimiliki oleh Faktur termasuk total() dapat dipanggil oleh FakturJual. Ini disebut sebagai prototype chaining. Dengan demikian, saya dapat membuat kode program seperti berikut ini:

var produkA = new Produk('Produk A', 120000, 10);
var produkB = new Produk('Produk B', 85000, 5);
var fakturJual = new FakturJual('FA-001', Date.now(), 10, 'Konsumen A');
fakturJual.tambah(produkA, 5, 130000);
fakturJual.tambah(produkB, 10, 12000);
console.log(fakturJual.total()); // output: 693000

Penggunaan prototype chaining memiliki efek samping pada nilai referensi seperti pada array. Sebagai contoh, bila saya membuat object FakturJual kedua, saya akan memperoleh kesalahan pada perhitungan total, seperti yang terlihat pada kode program berikut ini:

/** Contoh Penggunaan **/
var produkA = new Produk('Produk A', 120000, 10);
var produkB = new Produk('Produk B', 85000, 5);

var fakturJual1 = new FakturJual('FA-001', Date.now(), 10, 'Konsumen A');
fakturJual1.tambah(produkA, 5, 130000);
fakturJual1.tambah(produkB, 10, 12000);
console.log(fakturJual1.total()); // output: 693000

var fakturJual2 = new FakturJual('FA-002', Date.now(), 0, 'Konsumen B');
fakturJual2.tambah(produkA, 2, 125000);
console.log(fakturJual2.total()); // output: 1020000

Terlihat bahwa object fakturJual2 memiliki nilai items yang sama seperti yang dimiliki oleh fakturJual1. Bila saya memanggil fakturJual2.tambah(), maka item baru tersebut akan ditambahkan pada array yang di-share bersama tersebut. Hal ini bukan sesuatu yang saya harapkan karena saya ingin fakturJual2 memiliki items-nya sendiri.

Untuk mengatasi hal tersebut, saya dapat menggunakan constructor stealing dengan mengubah kode program seperti berikut ini:

function FakturJual(nomor, tanggal, diskon, konsumen) {
    Faktur.call(this, nomor, tanggal, diskon);    
    this.konsumen = konsumen;
}
FakturJual.prototype = new Faktur();

Setiap function di JavaScript adalah sebuah object dan memiliki method seperti call() untuk mengerjakannya dengan melewatkan this yang berbeda. Pada kode program di atas, saya melewatkan this yang mewakili object FakturJual baru ke function Faktur(). Dengan demikian seluruh properties milik Faktur akan dimiliki oleh Faktur. Saya juga tetap memakai prototype dari Faktur untuk FakturJual sehingga saya tetap hanya perlu men-override method sekali saja bila diperlukan. Dengan demikian, masing-masing instance dari FakturJual memiliki property-nya masing-masing, tetapi mereka tetap memakai method yang sama.

Kesimpulan: Karena JavaScript tidak mendukung inheritance melalui syntax-nya, maka penerapan inheritance dilakukan melalui pola kode program (pattern) seperti prototype chaining atau constructor stealing. Ini membuatnya lebih rentan terhadap kesalahan terutama bila sang programmer tidak waspada dalam menerapkan pola yang ada.

Perihal Solid Snake
I'm nothing...

Apa komentar Anda?

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: