Cara menggunakan METHHOD pada JavaScript

Fungsi method map pada JavaScript adalah untuk membuat array baru dari memanggil sebuah function pada setiap elemen array. contoh:

hasil : apel rasanya enak,pisang rasanya enak,rambutan rasanya enak,durian rasanya enak.

dari contoh tersebut ada sebuah variabel dengan nama buah, memiliki nilai berupa array dengan nilai apel, pisang, rambutan, dan durian, kemudian kita petakan variabel buah tersebut menggunakan bantuan method map[] dimana kalau dari contoh, dengan menambahkan sebuah kata ‘rasanya enak’, dan menghasilkan hasil seperti diatas. Saat akan menggunakan method map kita bisa membuat variabel baru, kemudian kita isi dengan sebuah variabel yang berisi array yang mau dipetakan seperti contoh ‘buah.map[]’ , kemudian didalam map kita kasih sebuah ‘current-value’ , disitu saya kasih sebuah nilai X, kemudian kita panggil X tersebut setelah arrow function. Kemudian kita bisa tambahkan output apa yang ingin dikeluarkan, seperti contoh diatas kita tambahkan ‘rasanya enak’, untuk menghasilkan tambahan tulisan rasanya enak, dari setiap nilai dari array tersebut.

Secara tradisional, pengembangan berorientasi objek [selanjutnya disebut PBO saja] merupakan salah satu teknik rekayasa perangkat lunak yang dirancang untuk menangani kemudahan perawatan program besar. Fitur-fitur yang ditawarkan PBO, dari pembungkusan [encapsulation] sampai ke pewarisan [inheritance] dapat digunakan untuk meningkatkan penghimpunan fokus [separation of concern] dan penggunaan kembali kode [code reuse]. Bahasa-bahasa yang memiliki kemampuan PBO biasanya juga memiliki spesifikasi sistem tipe data [type system] yang lengkap dan kompleks. Sistem tipe data ini sangat berguna, terutama untuk memudahkan penulis kode dalam melakukan pergantian tipe [casting]. Dengan adanya sistem tipe data yang baik, pengembang program tidak lagi perlu melakukan pergantian tipe secara eksplisit, dan mengorbankan keamanan program.

Javascript, sebagai bahasa yang bersifat duck typed atau loosely typed sangat fleksibel dalam menangani masalah tipe data ini. Hal ini juga lah yang menjadi alasan utama Javascript mengadopsi PBO prototype-based. Dengan menggunakan sistem tipe data fleksibel yang ditambahkan dengan pendekatan PBO yang tidak biasa, Javascript menawarkan pola penggunaan atau pola pemrograman yang berbeda dibandingkan bahasa lain pada umumnya.

Pada bagian ini kita akan melihat beberapa teknik untuk menggunakan objek dengan baik, berfokus pada penggunaan kembali kode. Pembahasan mengenai interaksi antar objek [khususnya design pattern] tidak akan dilakukan, karena hal ini akan memerlukan buku tersendiri.

Pembuatan Objek¶

Dari bab-bab sebelumnya, kita telah melihat dua cara utama untuk membuat objek. Cara yang pertama adalah dengan menggunakan notasi pembuatan objek:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15

var mobil = {
    warna: "",
    bahan_bakar: "",
    kode_mobil: function [] {
        return this.warna[0] + this.bahan_bakar[0];
    }
};

var mobilMerah = Object.create[mobil];
mobilMerah.warna = "Merah";
mobilMerah.bahan_bakar = "Bensin";

// menghasilkan
// { warna: 'Merah', bahan_bakar: 'Bensin', kode_mobil: [Function] }
console.log[mobilMerah];

Cara kedua adalah dengan menggunakan closure:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

// w dan bb merupakan parameter yang dikirimkan
// ke objek.
// w untuk warna mobil
// bb untuk bahan bakar
var mobil = function [w, bb] {
        var warna = w,
            bahan_bakar = bb,
            kode_mobil = function [] {
                return this.warna[0] + this.bahan_bakar[0];
            };

        return {
            warna: warna,
            bahan_bakar: bahan_bakar,
            kode_mobil: kode_mobil
        };
    };

    var mobilMerah = mobil["Merah", "Bensin"];

// menghasilkan
// { warna: 'Merah', bahan_bakar: 'Bensin', kode_mobil: [Function] }
console.log[mobil];

Kita lebih menyukai cara kedua, karena pada cara kedua kita memiliki variabel ataupun method privat. Tentu saja kedua cara pembuatan objek ini memiliki kegunaannya masing-masing. Terkadang, jika objek yang dibuat hanya menyimpan data sederhana, kita tidak perlu membuat closure. Selalu pastikan kode yang kita tuliskan adalah kode yang paling sederhana.

Penambahan Fungsionalitas Objek¶

Sama seperti properti, kita dapat menambahkan method pada sebuah objek turunan dengan cara yang sama seperti menambahkan properti:

var ayam = {
        sayap: 2,
        kaki: 2
    };

    var burung = Object.create[ayam];
    burung.terbang = function [] {
        return "t-t-t-terbang!";
    }

    burung.terbang[]; // mencetak "t-t-t-terbang!"

Penambahan fungsionalitas ini tidak hanya dapat dilakukan terhadap objek yang kita buat sendiri saja. Objek-objek dasar seperti Function, Object maupun yang lainnya dapat ditambahkan fungsionalitasnya.

Contohnya, kita dapat menambahkan fungsionalitas baru untuk menambahkan fungsi method ke objek Function agar semua objek bawaan Javascript dapat menambahkan method dengan mudah:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

Function.prototype.method = function [name, func] {
    // pastikan method belum ada sebelumnya.
    if [!this.prototype[name]] {
        this.prototype[name] = func;
        return this;
    }
};

// contoh penggunaan: menambahkan fungsi "bulatkan"
// pada semua bilangan yang ada dalam Javascript.
Number.method["bulatkan", function [] {
    return Math.floor[this];
}];

var nilai = 10.33;
nilai.bulatkan[]; // mencetak 10

Pada contoh di atas, kita menambahkan fungsi ke Function karena objek bawaan Javascript semuanya merupakan turunan dari Function. Hal ini disebabkan oleh kesalahan perancangan Javascript, yang menggunakan Constructor Invocation Pattern untuk semua objek dasarnya. Jika kita mau, tentunya kita dapat langsung menambahkan fungsi method di atas pada Object, agar objek buatan kita juga memiliki fungsi ini.

Pewarisan [Inheritance]¶

Kemampuan membuat atau menambahkan fungsi objek saja seringkali tidak cukup ketika kita mengembangkan aplikasi. Seringkali kita memerlukan sebuah objek baru yang memiliki fungsionalitas hampir sama dengan objek yang sudah ada. Jika mayoritas dari properti dan method objek lama sama dengan objek baru, tentunya membuat objek baru sangatlah boros.

Untuk menyelesaikan permasalahan di atas, PBO menawarkan konsep pewarisan [inheritance].

Secara umum ide dari pewarisan adalah sebuah objek dapat mewariskan properti maupun method miliknya ke objek lain. Objek yang mendapatkan warisan kemudian akan memiliki method dan properti yang sama, dan bebas mengubah nilai dari properti maupun method tersebut tanpa mempengaruhi nilai objek yang mewariskan. Dengan kemampuan untuk menambah ataupun mengubah inilah kita bisa menyelesaikan masalah objek mirip. Wariskan objeknya, kemudian ganti bagian yang perlu berubah.

Karena kita memiliki dua cara untuk membuat objek, tentunya kita juga akan memiliki dua cara untuk membuat pewarisan:

  1. Ketika kita melakuukan pewarisan terhadap objek secara langsung, kita memanfaatkan fitur pewarisan milik Javascript, yaitu prototype. Pewarisan model ini akan kita sebut sebagai Pewarisan dengan Prototype.
  2. Jika kita ingin melakukan pewarisan terhadap objek yang dibuat dengan closure, kita akan memerlukan cara khusus. Karena closure merupakan konsep pemrograman fungsional, kita akan menamakan cara ini Pewarisan secara Fungsional.

Mari kita lihat kedua cara tersebut.

Pewarisan dengan Prototype¶

Pewarisan dengan Prototype telah kita bahas sedikit pada bab sebelumnya. Konsep dari pewarisan jenis ini sangat sederhana. Kita memiliki sebuah objek yang sangat berguna. Katakanlah kita memerlukan objek yang hampir sama dengan objek tersebut, dengan perbedaan hanya pada cara kerja satu method saja. Kita dapat membuat turunan objek tersebut secara langsung, dan mengubah method yang cara kerjanya berbeda saja. Tidak perlu ada beberapa tingkat kelas abstrak atau model turunan yang membingungkan.

Misalkan kita memiliki sebuah objek yang sangat berguna:

var manusia = {
    nama: "Scott",
    mata: 2,
    buka_mata: function [] {
        console.log["Mata membuka maka manusia melihat."];
    }
};

Setelah memiliki objek yang berguna seperti di atas, kita kemudian dapat membuat instan objek yang sama dengan menggunakan Object.create, seperti yang dijelaskan pada bab sebelumnya. Hasil instan objek tersebut kemudian dapat kita ubah sesuai keperluan:

var mutan = Object.create[manusia];
mutan.nama = "Cyclops";
mutan.mata = 1;
mutan.buka_mata = function [] {
    console.log["Mutan membuka mata dan yang di depan mata meledak."];
};

Yang kita lakukan di atas lebih dikenal dalam dunia pemrograman sebagai differential inheritance. Intinya, ketika kita membuat objek baru dan mengubahnya, sembari menspesifikasikan perbedaan objek baru dengan objek asalnya.

Pewarisan secara Fungsional¶

Pewarisan model fungsional memiliki bentuk yang agak berbeda dengan pewarisan pada umumnya. Karena pembuatan objek yang juga berbeda, maka kita akan memerlukan pendekatan yang sedikit berbeda. Sebelum mulai membicarakan tentang cara mewariskan secara fungsional, mari kita lihat kembali dan sempurnakan pembuatan objek secara fungsional.

Ketika membuat objek secara fungsional, pada dasarnya yang kita buat adalah constructor dari objek, yang memanfaatkan closure untuk membuat nilai privat dari objek. Jika kita telaah lebih lanjut, constructor ini memiliki empat tugas utama:

  1. Mendeklarasikan variabel maupun fungsi yang bersifat privat. Seluruh nilai-nilai privat ini dibuat hanya dengan menggunakan var biasa saja.
  2. Membuat objek baru yang nantinya akan dikembalikan oleh fungsi. Pembuatan objek baru dapat dilakukan dengan cara apapun, mulai dari {}, Object.create, ataupun closure.
  3. Tambahkan method ataupun variabel baru untuk objek yang baru dibuat, jika diperlukan. Nilai yang dibuat di sini merupakan nilai publik yang dapat diakses oleh pengguna objek. Seluruh method untuk objek ini dapat mengakses nilai-nilai privat yang telah dibuat pada langkah pertama.
  4. Mengembalikan objek baru yang telah selesai dibuat.

Pada contoh-contoh sebelumnya, langkah dua sampai empat kita jalankan dalam satu perintah, yaitu pada saat pembuatan objek ketika pemanggilan return. Meskipun seringkali hal ini sudah cukup, terkadang kita perlu menuliskan ketiga langkah tersebut secara eksplisit untuk menjaga kerapian kode, terutama jika objek yang dibuat besar dan memiliki banyak fungsionalitas.

Jika menggunakan pola di atas, fungsi constructor kita akan menjadi sedikit lebih rapi, dan dapat dipisahkan dengan baik langkah demi langkah pembuatannya. Pemisahan ini akan memudahkan kita ketika ingin mengubah fungsionalitas objek. Misalkan kita ingin membuat sebuah objek negara:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

    var negara = function [data] {
        // langkah 1 [nilai-nilai privat]
        var nama = data.nama || "Negara Kosong",
            penduduk = data.penduduk || 0,
            benua = data.benua || "Benua Kosong",
            dataLengkap = function [] {
                return nama + " " + penduduk + " " + benua;
            },
            jumlahPenduduk = function [] {
                return penduduk;
            },
            setJumlahPenduduk = function [jumlahBaru] {
                penduduk = jumlahBaru;
            },
            // langkah 2 [membuat objek baru]
            that = {};

        // langkah 3 [tentukan nilai publik]
        that.dataNama = function [] {
            return nama;
        };
        that.dataLengkap = dataLengkap;
        that.dataPenduduk = jumlahPenduduk;
        that.setDataPenduduk = setJumlahPenduduk;

        // langkah 4 [kembalikan objek]
        return that;
    };

Pada contoh di atas, kita membuat constructor untuk objek negara yang menerima parameter berupa objek berisi data negara yang ingin dibuat. Nilai data kemudian diisikan pda semua variabel privat yang ada, dan beberapa nilai digunakan untuk fungsi privat.

Langkah pertama dari tahap pembuatan objek di atas cukup jelas, di mana kita hanya membuat variabel dan fungsi saja. Langkah kedua juga cukup mudah, pembuatan objek kosong dengan nama that. Objek yang dikembalikan tidak wajib diberi nama that, tetapi nama ini sangat umum digunakan.

Pada langkah ketiga, kita mengisikan method publik yang akan dimiliki that. Beberapa hal yang perlu diperhatikan pada langkah ini:

  • Pembuatan method dapat dilakukan dengan dua cara. Cara pertama yaitu dengan langsung membuat fungsi baru ke variabel milik that. Jalan kedua adalah dengan mengikatkan fungsi privat ke fungsi publik. Cara pembuatan method publik kedua lebih disarankan, karena lebih aman. Misalnya, jika method that.dataLengkap disabotase, fungsi-fungsi lain di dalam objek yang memanggil method ini tidak akan terpengaruh karena sebenarnya mereka memanggil fungsi privat.
  • Nama dari method publik tidak harus sama dengan method privat, meskipun kita hanya mengikatkan method privat ke publik. Contoh jelasnya, lihat dataPenduduk dan setDataPenduduk.

Langkah keempat pastinya tidak memerlukan penjelasan lebih lanjut.

Penggunaan dari constructor negara juga sangat mudah. Cukup buat data yang diperlukan, kemudian panggil fungsi negara:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

var dataIndonesia = {
        nama: "Indonesia",
        penduduk: 400000000,
        benua: "Asia"
    };

    var indonesia = negara[dataIndonesia];

    indonesia.nama;           // mencetak undefined

    indonesia.dataNama[];     // mencetak "Indonesia"
    indonesia.dataPenduduk[]; // mencetak 400000000
    indonesia.dataLengkap[];  // mencetak "Indonesia 400000000 Asia"

    indonesia.setDataPenduduk[410000000];
    indonesia.dataPenduduk[]; // mencetak 410000000

Oke, cukup mudah dan jelas. Mari kita kembali ke topik pewarisan. Bagaimana melakukan pewarisan dengan cara fungsional? Sederhana, kita cukup mengisikan that dengan objek pewaris yang diinginkan. Dengan mengisikan that maka kita dapat menambahkan dan mengubah properti maupun method dari that. Karena objek turunan memiliki constructor tersendiri, maka kita juga dapat menambahkan nilai privat ke objek turunan.

Langsung saja, contoh jika kita ingin menurunkan objek negara:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17

    var provinsi = function [data] {
        // validasi data
            // untuk memastikan data yang dikirimkan ke
            // negara tidak kosong / salah.
        data.nama = data.nama || "Nama Kosong";
        data.penduduk = data.penduduk || 0;
        data.benua = data.benua || "Benua Kosong";

        var pulau = data.pulau || "Pulau Kosong",
            that = negara[data]; // that merupakan negara

        that.dataLengkap = function [] {
            return data.nama + " " + pulau + " " + that.dataPenduduk[];
        };

        return that;
    };

Pada objek provinsi di atas, kita mendapatkan warisan dari negara dengan sangat mudah. Dengan memanggil constructor negara maka kita mengisikan that dengan objek negara. Kita lalu mengubah method dataLengkap dengan menambahkan informasi baru ke nilai kembalian. Lihat juga bahwa kita tidak memanggil that.dataLengkap, karena pemanggilan that.dataLengkap di dalam dirinya sendiri akan menyebabkan pemanggilan fungsi secara berputar-putar tanpa akhir. Coba ganti that.dataPenduduk dengan that.dataLengkap untuk melihat efeknya.

Kita dapat mencoba menggunakan objek provinsi di atas seperti berikut:

var dataJakarta = {
        nama: "Jakarta",
        penduduk: 1000000,
        benua: "Asia",
        pulau: "Jawa"
    };

    var jakarta = provinsi[dataJakarta];

    jakarta.dataLengkap[]; // mencetak "Jakarta Jawa 1000000"

Pewarisan secara fungsional seperti ini juga memungkinkan kita memanggil method milik objek asal. Pada bahasa lain umumnya kita memanggil nilai pada objek asal dengan menggunakan kata kunci super. Mengikuti konvensi yang sudah ada, mari kita kembangkan fungsi yang memberikan kita kemampuan ini:

// ingat Function.prototype.method pada contoh di awal bab
Object.method['super', function [name] {
    var that = this,
        method = that[name];

    return function [] {
        return method.apply[that, arguments];
    };
}];

Fungsi super cukup gamblang. Kita hanya mengambil nilai objek sekarang, dan menjalankan method objek tersebut secara tidak langsung. Nilai kembalian diberikan berupa fungsi yang masih harus dieksekusi. Hal ini dibuat untuk meningkatkan fleksibilitas. Penggunaan fungsi ini adalah sebagai berikut:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20

var provinsi = function [data] {
        // validasi data
            // untuk memastikan data yang dikirimkan ke
            // negara tidak kosong / salah.
        data.nama = data.nama || "Nama Kosong";
        data.penduduk = data.penduduk || 0;
        data.benua = data.benua || "Benua Kosong";

        var that = negara[data], // that merupakan negara
            pulau = data.pulau || "Pulau Kosong",
            super_dl = that.super['dataLengkap']; // pemanggilan super

        that.dataLengkap = function [] {
            return pulau + " " + super_dl[];
        };

        return that;
    };

    jakarta.dataLengkap[]; // mencetak "Jawa Jakarta 1000000 Asia"

Sejauh ini, kita dapat melihat bagaimana pewarisan secara fungsional memberikan kita pembungkusan informasi dan akses ke method pada objek induk. Kedua hal ini, ditambahkan dengan konsep PBO yang baik akan memberikan kita objek yang sangat aman dan stabil.

Dengan pembungkusan informasi, kita dapat menyimpan semua data keadaan objek. Dengan membuat data keadaan menjadi privat, kita akan mendapatkan objek yang tahan banting. Perubahan objek hanya dapat dilakukan melalui method publik, dan secara otomatis lebih mudah diprediksi. Properti dan method dari objek dapat diubah, tetapi karena tidak dapat mengubah nilai privat, integritas objek tetap terjaga. Selama objek tidak menggunakan nilai this dan that, maka objek dapat dikatakan objek yang durable. Objek durable merupakan objek yang hanya berupa kumpulan fungsi yang berlaku sebagai capability dari objek tersebut.

Objek yang durable tidak dapat dengan mudah diserang. Jika penyerang berhasil mendapatkan kontrol pada objek durable, si penyerang tetap tidak dapat mengubah data keadaan objek tersebut.

Kombinasi Objek [Mixin]¶

Ketika mengembangkan aplikasi berorientasi objek terkadang kita ingin menggunakan satu atau dua fungsi saja dari sebuah objek pada objek yang sedang aktif sekarang. Menambahkan objek tersebut sebagai properti dari objek yang aktif terasa sangat mubazir, terutama jika fungsi tersebut benar-benar hanya dipanggil sekali. Hal seperti ini sering dihadapi, dan akhirnya kita harus membuat pertimbangan apakah ingin meningkatkan kompleksitas kode dengan membuat objek baru atau mengurangi kemudahan perawatan dengan mengimplementasikan dua fungsi sama pada objek yang berbeda.

Dalam Javascript, hal di atas dapat diatasi dengan teknik yang dikenal dengan nama Mixin. Konsep mixin sangat sederhana: kita “menggabungkan” dua atau lebih objek dengan hanya mengambil method atau properti baru yang diperlukan dari masing-masing objek. Bayangkan objek Javascript sebagai lego, yang dapat dipecah-pecah menjadi potongan kecil dan potongan tersebut dapat dipasangkan ke lego yang lain. Dengan cara ini kita dapat mengambil bagian yang diperlukan dari sebuah objek dan memasangkannya ke objek lain.

Implementasi dari mixin juga sagnat sederhana. Pada bagian sebelumnya kita telah melihat bagaimana kita dapat menggunakan method hasOwnProperty untuk melakukan pengecekan properti asli dari fungsi, dan bagaimana menambahkan method baru ke dalam objek dengan menggunakan prototype. Dengan menggabungkan kedua hal tersebut kita bisa mendapatkan mixin:

function mixin[asli, gabung] {
    for [prop in gabung] {
        if [!asli.hasOwnProperty[prop]] {
            asli[prop] = gabung[prop];
        }
    }
    }

Fungsi mixin di atas melakukan hal yang sangat sederhana. Variabel asli merupakan objek yang ingin menggunakan satu atau semua method dari objek gabung. Pertama, kita melakukan penelusuran terhadap properti milik gabung, kemudian memastikan properti tersebut tidak dimiliki oleh asli melalui fungsi hasOwnProperty. Setelah itu, kita langsung menambahkan properti baru ke dalam asli, diisikan dengan nilai yang sama dengan properti milik gabung. Properti baru ini adalah properti milik gabung yang kita telusuri.

Berikut adalah contoh penggunaan fungsi mixin di atas:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22

var sapu = {
    nama: "nimbus"
}

var pesawat = {
    model: "2000",
    terbang: function [] {
        return "ngoooong";
    }
};

mixin[sapu, pesawat];

console.log[sapu];
// hasil:
// {
//     nama: 'nimbus',
//     model: '2000',
//     terbang: function [] {
//         return "ngoooong";
//     }
// }

Sangat mudah bukan? Sayangnya penggabungan seluruh properti objek seperti di atas tidak selalu kita inginkan. Seperti yang dijelaskan di awal, terkadang kita hanya ingin menggunakan satu properti atau method saja. Kita dapat mengganti mixin utnuk menambahkan kemampuan ini:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15

function mixin[asli, gabung] {
    if [arguments.length > 2] {
        for [var i = 2, len = arguments.length; i  Hello World!
		
			

Apa itu OOP pada JavaScript?

Apa itu OOP [Object Oriented Programming]? OOP adalah singkatan dari Object Oriented Programming, yaitu suatu metode pemrograman yang fokus atau berorientasi pada objek. Tujuan dari dirancangnya OOP adalah membantu para developer dalam mengembangkan model yang sudah ada di kehidupan sehari-hari.

Bài mới nhất

Chủ Đề