Membuat Event Dan Menambahkan Fungsi
Beberapa tahun terakhir, JavaScript semakin meraih popularitas, antara lain disebabkan dengan banyaknya pustaka (library) yang dikembangkan agar penerapan serta penggunaan JavaScript menjadi lebih mudah terutama bagi mereka yang mungkin belum sepenuhnya memahami bahasa inti dari JavaScript.
Sementara, dulu umumnya JavaScript hanya dianggap sebagai bahasa serampangan, yang tidak memiliki prinsip dasar yang kuat; hal ini bukan lagi menjadi persoalan lantaran dengan munculnya banyak aplikasi web JavaScript berskala tinggi dan beberapa 'adaptasi' seperti JSON (JavaScript Object Notation).
JavaScript dapat memiliki semua hal yang ditawarkan oleh bahasa-bahasa pemrograman berorientasi objek, meskipun dengan beberapa upaya ekstra diluar cakupan artikel ini.
Mari Membuat Sebuah Objek
1
2
3
| function myObject(){ }; |
Selamat, anda telah membuat sebuah objek. Ada dua cara untuk membuat sebuah objek JavaScript yaitu dengan fungsi 'constructor' dan notasi 'literal'. Yang telah kita buat di atas adalah sebuah fungsi constructor dan berikut adalah cara mendefinisikan sebuah Object dalam JavaScript dengan menggunakan notasi literal.
1
2
3
| var myObject = { }; |
Literal adalah cara yang lebih dianjurkan untuk name spacing sehingga kode JavaScript anda tidak menghalangi script lain (atau juga sebaliknya) yang sedang berjalan di dalam satu halaman tersebut, juga jika anda menggunakan objek hanya sebagai satu objek dan tidak membutuhkan lebih dari satu permisalan. Sedangkan penggunaan fungsi constructor lebih dianjurkan jika anda harus menjalankan beberapa fungsi awal sebelum objek tersebut dibuat atau membutuhkan banyak permisalan dari objek tersebut, di mana setiap permisalan dapat diubah selama rentang waktu script tersebut. Untuk lebih jelasnya, mari kita lanjutkan dengan membuat dua tipe objek secara bersamaan sehingga kita dapat melihat perbedaannya.
Mendefinisikan Method dan Property
Versi Constructor:
1
2
3
4
5
6
| function myObject(){ this .iAm = 'an object' ; this .whatAmI = function (){ alert( 'I am ' + this .iAm); }; }; |
Versi Literal:
1
2
3
4
5
6
| var myObject = { iAm : 'an object' , whatAmI : function (){ alert( 'I am ' + this .iAm); } } |
Di dalam setiap objek di atas, baik dalam versi constructor atau literal, kita telah membuat sebuah property bernama 'iAM' yang mengandung nilai string yang kemudian kita gunakan di dalam sebuah method bernama 'whatAmI' yang akan menampilkan sebuah alert/pesan.
Property adalah variabel yang dibuat di dalam sebuah objek, dan sedangkan method ialah fungsi yang dibuat di dalam sebuah objek.
Sekarang kita akan melihat bagaimana menggunakan property dan method tersebut (sebenarnya anda telah melakukannya jika anda telah akrab dengan penggunaan sebuah pustaka).
Untuk menggunakan sebuah property, pertama anda menuliskan objek dimana ia ditempatkan ‐ jadi dalam contoh ini adalah
myObject
‐ kemudian tambahkan sebuah titik yang diikuti oleh nama property internal, sehingga ia akan nampak seperti ini: myObject.iAm
(contoh ini akan menghasilkan 'an object').
Penggunaan method pada prinsipnya sama, hanya berbeda pada eksekusi. Seperti umumnya sebuah fungsi JavaScript, anda harus meletakkan tanda kurung setelahnya; jika tidak anda hanya akan menghasilkan sebuah referensi fungsi dan bukannya menghasilkan keluaran dari fungsi tersebut. Jadi, ia akan tampak seperti ini:
myObject.whatAmI()
(contoh ini akan menampilkan pesan yang berisikan 'I am an object')Perbedaannya:
- Di dalam Objek constructor, penggunaan property dan method dimulai dengan menggunakan kata kunci 'this', sedangkan versi literal tidak.
- Nilai di dalam Objek constructor ditentukan setelah tanda sama-dengan '=', sedangkan di dalam versi literal, nilai didefinisikan setelah tanda titik-dua ':'.
- Fungsi constructor dapat memiliki (pilihan) titik-koma pada akhir masing-masing property/method, sedangkan di dalam versi literal jika anda memiliki lebih dari satu property atau method, mereka harus dipisahkan dengan koma ',', dan TIDAK dapat memiliki tanda titik-koma setelahnya ';', jika tidak JavaScript akan menghasilkan error.
Ada juga sebuah perbedaan antara cara kedua tipe objek ini digunakan.
Untuk menggunakan objek literal, and cukup mereferensikannya dengan nama variable, sehingga anda menuliskannya seperti berikut;
1
| myObject.whatAmI(); |
Dengan fungsi constructor anda harus membuat permisalan baru dari objek tersebut; sehingga penulisannya adalah sebagai berikut;
1
2
| var myNewObject = new myObject(); myNewObject.whatAmI(); |
Menggunakan Fungsi Constructor
Mari kita gunakan dan mengembangkan fungsi constructor kita sebelumnya, sehingga fungsi tersebut melakukan beberapa operasi dasar (namun juga dinamis) ketika kita menjalankannya.
1
2
3
4
5
6
| function myObject(){ this .iAm = 'an object' ; this .whatAmI = function (){ alert( 'I am ' + this .iAm); }; }; |
Seperti umumnya fungsi JavaScript, kita dapat melewatkan argumen ke dalam fungsi constructor kita;
1
2
3
4
5
6
| function myObject(what){ this .iAm = what; this .whatAmI = function (language){ alert( 'I am ' + this .iAm + ' of the ' + language + ' language' ); }; }; |
Sekarang, mari kita membuat permisalan baru dengan memanggil method 'whatAmI', dan kemudian mengisikan nilai ke dalam kolom argumen fungsi tersebut.
1
2
| var myNewObject = new myObject( 'an object' ); myNewObject.whatAmI( 'JavaScript' ); |
Contoh ini akan menghasilkan pesan 'I am an object of the JavaScript language.'
Membuat Permisalan atau Tidak
Saya menyebutkan di awal tentang perbedaan antara objek constructor dan objek literal. Ketika sebuah perubahan terjadi pada objek literal, maka ia akan berdampak pada keseluruhan objek di dalam script, sedangkan ketika sebuah fungsi constructor telah dibuat ke dalam permisalan baru, dan kemudan terjadi perubahan pada permisalan tersebut, ia tidak akan berdampak pada permisalan-permisalan yang lain dari objek tersebtu. Mari kita ambil sebuah contoh;
Pertama kita akan membuat sebuah objek literal;
01
02
03
04
05
06
07
08
09
10
11
12
| var myObjectLiteral = { myProperty : 'this is a property' } //tampilkan pesan myProperty terkini alert(myObjectLiteral.myProperty); //ini akan menampilkan 'this is a property' //ubah myProperty myObjectLiteral.myProperty = 'this is a new property' ; //tampilkan myProperty terkini alert(myObjectLiteral.myProperty); //ini akan menampilkan pesan 'this is a new property', seperti yang diduga |
Bahkan jika anda membuat sebuah permisalan baru dan menujukannya terhadap objek tersebut, ia akan menghasilkan efek yang sama.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
| var myObjectLiteral = { myProperty : 'this is a property' } //tampilkan pesan myProperty terkini alert(myObjectLiteral.myProperty); //ini akan menampilkan pesan 'this is a property' //mendefinisikan variabel baru dengan objek sebagai nilainya var sameObject = myObjectLiteral; //ubah myProperty myObjectLiteral.myProperty = 'this is a new property' ; //tampilan pesan myProperty terkini alert(sameObject.myProperty); //ini akan tetap menampilkan 'this is a new property' |
Sekarang mari kita coba contoh yang sama dengan sebuah fungsi constructor.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
| //this is one other way of creating a Constructor function var myObjectConstructor = function (){ this .myProperty = 'this is a property' } //membuat permisalan Constructor kita var constructorOne = new myObjectConstructor(); //membuat permisalan ke dua untuk Constructor kita var constructorTwo = new myObjectConstructor(); //tampilkan pesan dari permisalan constructorOne dari myProperty terkini alert(constructorOne.myProperty); //this will alert 'this is a property' //tampilkan pesan dari permisalan constructorTwo dari myProperty terkini alert(constructorTwo.myProperty); //this will alert 'this is a property' |
Seperti yang diharapkan, keduanya menghasilkan nilai yang benar, namun mari kita ubah
myProperty
untuk salah satu dari kedua permisalan di atas.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
| //ini adalah salah satu cara lain untuk membuat sebuah fungsi Constructor var myObjectConstructor = function (){ this .myProperty = 'this is a property' } //membuat permisalan untuk Constructor kita var constructorOne = new myObjectConstructor(); //ubah myProperty dari permisalan pertama constructorOne.myProperty = 'this is a new property' ; //membuat permisalan kedua dari Constructor kita var constructorTwo = new myObjectConstructor(); //tampilkan pesan myProperty terkini dari permisalan constructorOne alert(constructorOne.myProperty); //ini akan menampilkan pesan 'this is a new property' //tampilkan pesan myProperty terkini dari permisalan constructorTwo alert(constructorTwo.myProperty); //ini tetap akan menampilkan pesan 'this is a property' |
Seperti yang dapat anda lihat pada contoh di atas, walaupun kita telah mengubah property dari contructorOne ia tidak mempengaruhi myObjectContructor dan oleh karena itu juga tidak mempengaruhi constructorTwo. Bahkan jika constructorTwo dimisalkan sebelum kita mengubah property myProperty dari constructorOne, ia tetap tidak akan mempengaruhi property myProperty dari constructorTwo karena ia merupakan permisalan yang sama sekali berbeda dari objek yang terdapat di dalam memori JavaScript.
Jadi manakah yang seharusnya anda gunakan? Jawabnya tergantung dari situasi. Jika anda hanya ingin satu objek dari jenisnya untuk script anda (seperti yang akan anda lihat pada contoh di akhir artikel ini), maka gunakan objek literal. Namun jika anda membutuhkan beberapa permisalan dari satu objek tersebut, di mana masing-masing permisalan terlepas dari yang lain dan dapat memiliki property atau method berbeda, tergantung dari cara ia dikonstruksikan, maka gunakan fungsi constructor.
This dan That
Kata kunci 'this' yang banyak kita gunakan di dalam constructor berkaitan dengan scope atau cakupan. Cakupan di dalam JavaScript adalah fungsi/objek berdasar, yaitu ketika anda berada di luar sebuah fungsi, anda tidak dapat menggunakan sebuah variabel yang tidak terdefinisi di dalam fungsi tersebut (kecuali jika anda memakai closure).
Namun ada sebuah rantai cakupan, yaitu bahwa sebuah fungsi di dalam fungsi yang lain dapat mengakses sebuah variabel yang ada di dalam fungsi induk. Mari kita lihat beberapa contoh berikut.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
| <script type= "text/javascript" > var var1 = 'this is global and is available to everyone' ; function function1(){ var var2 = 'this is only available inside function1 and function2' ; function function2(){ var var3 = 'this is only available inside function2' ; } } </script> |
Seperti yang anda lihat pada contoh ini,
var1
didefinisikan di dalam objek global dan tersedia untuk semua fungsi dan objek. var2
didefinisikan di dalam function1
dan tersedia untuk function1
dan function2
, namun jika anda mencoba untuk mereferensikannya dari objek global ia akan menghasilkan error 'var2 is undefined', karena var3
hanya dapat diakses di function2
.
Jadi apa yang direferensikan oleh 'this' di sini? Di dalam sebuah browser, 'this' mereferensikan objek window, jadi secara teknis window adalah objek global kita. Jika kita berada di dalam sebuah objek, 'this' akan menuju ke pada objek itu sendiri, akan tetapi jika anda berada di dalam sebuah fungsi, 'this' tetap akan menunjuk ke pada window objek dan begitu pula jika anda di dalam sebuah method yang berada di dalam sebuah objek, maka 'this' akan merujuk pada objek tersebut.
Karean cakupan rantai, jika anda berada di dalam sebuah sub-objek (sebuah objek di dalam sebuah objek), 'this' akan merujuk ke pada sub-objek dan bukan objek induk.
Sebagai catatan tambahan ketika menggunakan fungsi seperti
setInterval
, setTimeout
dan eval
, ketika Anda menjalankan fungsi atau metode melalui salah satu dari mereka, 'this' mengacu pada objek window karena fungsi-fungsi tersebut adalah objek window, sehingga setInterval()
dan window.setInterval()
adalah sama.
Baik! sekarang mari kita menerapkannya ke dalam sebuah contoh nyata dengan membuat sebuah objek validasi form.
Contoh Penggunaan: Membuat Objek Validasi Formulir
Pertama saya harus memperkenalkan anda kepada fungsi
addEvent
yang akan kita buat, serta adalah kombinasi dari fungsi addEventListener()
ECMAScript (Firefox, Safari, etc..) dan fungsi attachEvent()
Microsoft ActiveX Script.
1
2
3
4
5
6
7
8
9
| function addEvent(to, type, fn){ if (document.addEventListener){ to.addEventListener(type, fn, false ); } else if (document.attachEvent){ to.attachEvent( 'on' +type, fn); } else { to[ 'on' +type] = fn; } }; |
Di atas kita membuat sebuah fungsi baru dengan tiga argumen,
to
adalah objek DOM yang akan kita ikatkan dengan event, type
adalah jenis event, dan fn
adalah fungsi yang akan dijalankan ketika event tersebut dicetuskan. Pertama, ia akan memeriksa apakah addEventListener
didukung, jika didukung ia akan menggunakannya, jika tidak ia akan memeriksa attachEvent dan jika semua uji tersebut gagal anda mungkin menggunakan IE5 atau browser yang sudah usang sehingga kita akan menambahkan event langsung ke property event (catatan: opsi ke-tiga akan menimpa fungsi apapun yang ada yang mungkin telah tersemat ke property event, sedangkan dua opsi pertama akan menambahkannya sebagai fungsi tambahan dari event property).
Sekarang mari kita atur dokumen kita sehingga serupa dengan apa yang mungkin anda lihat ketika anda mengembangkan dengan menggunakan jQuery.
Di jQuery anda akan mendapati;
1
2
3
| $(document).ready( function (){ //semua kode yang berjalan setelah halaman siap ditambahkan di sini }); |
Dengan menggunakan fungsi
addEvent
kita, kita akan mendapati;
1
2
3
| addEvent(window, 'load' , function (){ //semua kode yang berjalan setelah halaman siap ditambahkan di sini }); |
Sekarang untuk objek Form kita.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| var Form = { validClass : 'valid' , fname : { minLength : 1, maxLength : 15, fieldName : 'First Name' }, lname : { minLength : 1, maxLength : 25, fieldName : 'Last Name' }, validateLength : function (formEl, type){ if (formEl.value.length > type.maxLength || formEl.value.length < type.minLength ){ formEl.className = formEl.className.replace( ' ' +Form.validClass, '' ); return false ; } else { if (formEl.className.indexOf( ' ' +Form.validClass) == -1) formEl.className += ' ' +Form.validClass; return true ; } }, validateEmail : function (formEl){ var regEx = /^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$/; var emailTest = regEx.test(formEl.value); if (emailTest) { if (formEl.className.indexOf( ' ' +Form.validClass) == -1) formEl.className += ' ' +Form.validClass; return true ; } else { formEl.className = formEl.className.replace( ' ' +Form.validClass, '' ); return false ; } }, getSubmit : function (formID){ var inputs = document.getElementById(formID).getElementsByTagName( 'input' ); for ( var i = 0; i < inputs.length; i++){ if (inputs[i].type == 'submit' ){ return inputs[i]; } } return false ; } }; |
Kode ini cukup sederhana dan mendasar, namun dapat dengan mudah dikembangkan lagi.
Rinciannya adalah: pertama kita membuat sebuah property baru dengan sebuah nilai string, 'valid', ialah nama kelas CSS kita yang ketika diaplikasikan ke dalam kolom formulir akan menampilkan efek validitas seperti garis hijau. Kita juga mendefinisikan dua sub-objek,
fname
dan lname
, sehingga kita dapat mendefinisikan property tersebut di mana saja, property tersebut adalah minLength
yaitu panjang maksimum karakter yang dapat ditampung oleh sebuah kolom formulir dan fieldName
yang sebenarnya tidak kita gunakan pada artikel ini, tapi bisa berguna seperti untuk menampilkan pesan error (contoh: 'First Name field is required').
Selanjutnya kita membuat sebuah method bernama
validateLength
yang menerima dua argumen: formEL
yaitu elemen DOM untuk validasi dan type
yang mengacu kepada satu dari dua sub-objek (yaitu fname
atau lname
). Fungsi ini memeriksa apakah panjang kolom di antara rentang minLength
dan maxLength
, jika tidak maka kemudia kita akan menghapis kelas 'valid' (jika ada) dari elemen dan menghasilkan false
, sebaliknya jika 'iya' make kita akan menambahkan kelas 'valid' dan menghasilkan true
.
Selanjutnya kita memiliki sebuah method bernama
validateEmail
yang menerima elemen DOM sebagai argumen, kita kemudian menguji nilai elemen DOM ini dengan regular expression untuk email; jika hasil uji valid maka kita akan menambahkan kelas 'valid' and menghasilkan true
dan begitupula sebaliknya.
Di akhir, kita memliki sebuah method beranama
getSubmit
. Method ini diberikan id dari formulir dan kemudian melakukan loop melalui semua elemen input di dalam formulir yang telah ditentukan untuk menemukan input yang memiliki jenis 'submit' (type="submit"). Alasan kita melakukan ini adalah agar tombol submit dapat kita non-aktifkan hingga semua input di dalam formulir tersbut siap untuk di-submit.
Mari letakkan objek validator agar bekerja di dalam sebuah formulir sungguhan. Pertama kita butuh HTML kita.
01
02
03
04
05
06
07
08
09
10
| <body> <form id= "ourForm" > <label>First Name</label><input type= "text" /><br /> <label>Last Name</label><input type= "text" /><br /> <label>Email</label><input type= "text" /><br /> <input type= "submit" value= "submit" /> </form> </body> |
Sekarang mari kita akses objek input menggunakan JavaScript dan memvalidasi mereka ketika formulir di-submit.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| addEvent(window, 'load' , function (){ var ourForm = document.getElementById( 'ourForm' ); var submit_button = Form.getSubmit( 'ourForm' ); submit_button.disabled = 'disabled' ; function checkForm(){ var inputs = ourForm.getElementsByTagName( 'input' ); if (Form.validateLength(inputs[0], Form.fname)){ if (Form.validateLength(inputs[1], Form.lname)){ if (Form.validateEmail(inputs[2])){ submit_button.disabled = false ; return true ; } } } submit_button.disabled = 'disabled' ; return false ; }; checkForm(); addEvent(ourForm, 'keyup' , checkForm); addEvent(ourForm, 'submit' , checkForm); }); |
Mari kita rinci kode ini.
Kita membungkus kode di dalam fungsi
addEvent
, sehingga ketika window termuat, kode tersebut akan jalan. Pertama, kita mengambil formulir kita dengan menggunakan ID dan meletakkannya ke dalam sebuah variabel bernama ourForm
, kemudian kita mengambil tombol submit kita (dengan menggunakan method getSubmit
dari objek Form kita) dan meletakkanya ke dalam sebuah variabel bernama submit_button
, dan kemudian mengatur atribut disabled
tombol submit menjadi 'disabled'.
Selanjutnya kita mendefinisikan sebuah fungsi bernama
checkForm
. Fungsi ini menyimpan semua input ke dalam kolom formulir sebagai array dan kita menyertakannya ke dalam variabel inputs
. Kemudian ia mendefinisikan beberapa pernyataan 'if' yang akan menguji masing-masing kolom di dalam input array terhadap method Form kita. Ini adalah alasan kita menghasilkan true
atau false
di dalam method kita, sehingga jika ia menghasilkan true
, kita melewatkan pernyataan 'if' tersebut dan melanjutkan ke baris selanjutnya, namun jika ia menghasilkan false
, kita keluar dari pernyataan 'if'.
Setelah definisi fungsi, kita menjalankan fungsi
checkForm
ketika halaman pertama kali termuat dan juga menyertakan fungsi untuk keyup event dan submit event.
Mungkin anda bertanya, mengapa kita menyertakan ke submit jika kita menonaktifkan tombol submit. Jika fokus anda saat ini berada di sebuah kolom input dan menekan tombol enter, ia akan berusaha untuk me-submit form tersebut dan kita harus menguji untuk alasan ini, inilah alasan fungsi
checkForm
kita menghasilkan true
(men-submit formulir) atau false
(tidak mensubmit formulir).Simpulan
Kita telah belajar bagaimana mendefinisikan jenis-jenis objek yang berbeda dengan JavaScript dan membuat property dan method di dalamnya. Kita juga telah belajar mengenai fungsi addEvent dan menggunakan objek kita dengan contoh nyata mendasar.
Ini mengakhiri bahasan kita tentang JavaScript Berorientasi Objek. Saya harap, ini dapat menjadi awal anda untuk membuat pustaks anda sendiri. Jika anda menyukai artikel ini dan tertarik dengan topik JavaScript terkait, masukkan di komentar, saya akan dengan senang hati menulisnya. Terima kasih telah membaca.
Tidak ada komentar:
Posting Komentar