Sunday, December 25, 2016

Bab 6. Pemrograman Internet


JavaScript: Fungsi







6.1 Pengantar

Hampir semua program komputer yang dirancang untuk menyelesaikan permasalahan-permasalahan di dunia nyata jauh lebih besar dan kompleks daripada program-program yang disajikan pada bab-bab terdahulu dalam buku ini. Pengalaman membuktikan bahwa cara terbaik dalam mengembangkan sebuah program besar adalah dengan mengkonstruksinya dari potongan-potongan kecil dan sederhana (modul). Bab ini akan menjelaskan banyak fitur kunci JavaScript yang memfasilitasi perancangan, implementasi, operasi, dan pengembangan skrip.


6.2 Fungsi
Modul di dalam JavaScript dikenal dengan fungsi. Program JavaScript dituliskan dengan menggabungkan fungsi-fungsi baru yang Anda tulis dengan fungsi-fungsi paket dan objek-objek yang tersedia pada JavaScript. Fungsi paket dari objek JavaScript (seperti Math.pow dan Math.round, yang telah dikenalkan sebelumnya) dinamakan dengan metode. Istilah metode mengimplikasikan bahwa fungsi melekat pada objek tertentu. Fungsi yang melekat pada objek tertentu diistilahkan dengan metode; semua fungsi lain diistilahkan dengan fungsi.

JavaScript menyediakan beberapa objek yang memiliki koleksi yang kaya akan metode-metode (untuk melakukan perhitungan matematik, manipulasi string, manipulasi tanggal dan waktu, dan manipulasi koleksi data yang dikenal dengan array). Objek seperti ini menyediakan banyak kapabilitas yang sering Anda butuhkan. Beberapa objek terpradefinisi dari JavaScript dan metode-metodenya akan didiskusikan pada Bab 8 dan Bab 9.

Anda dapat menuliskan fungsi untuk mendefinisikan tugas spesifik yang dapat dipakai pada banyak titik di dalam skrip. Fungsi ini disebut dengan fungsi terdefinisi-pengguna. Statemen aktual yang mendfinisikan fungsi dituliskan hanya sekali dan tersembunyi dari fungsi lain.

Fungsi dipanggil dengan menuliskan nama fungsi, diikuti dengan sebuah kurung pembuka, diikuti dengan daftar argumen yang dipisahkan dengan koma, dan diikuti dengan sebuah kurung penutup. Sebagai contoh, seorang programer yang ingin mengkonversi sebuah string yang disimpan di dalam variabel nilaiMasukan menjadi sebuah angka pecahan dan menambahkannya pada variabel total dapat dituliskan sebagai

total += parseFloat( nilaiMasukan );

Ketika statemen ini dieksekusi, fungsi JavaScript, parseFloat, mengkonversi string di dalam variabel nilaiMasukan menjadi sebuah nilai pecahan dan menambahkan nilai tersebut kepada total. Variabel nilaiMasukan merupakan argumen dari fungsi parseFloat. Fungsi parseFloat mengambil suatu representasi string atas angka pecahan sebagai argumennya dan menghasilkan nilai balik berupa angka numerik pecahan terkait. Argumen fungsi dapat berupa konstanta, variabel, atau ekspresi.

Metode dipanggil dengan cara yang sama, tetapi memerlukan nama objek dimana metode tersebut dilekatkan dan sebuah dot (.) di depan nama metode. Sebagai contoh, Anda telah melihat sintaks document.writeln(“Hallo semua.”);. Statemen ini memanggil metode writeln dari objek document untuk menampilkan teks.


6.3 Fungsi Terdefinisi-Pengguna
Fungsi memampukan Anda untuk memodularisasi sebuah program. Semua variabel yang dideklarasikan di dalam definisi fungsi adalah variabel lokal. Variabel lokal hanya dapat diakses di dalam fungsi dimana ia didefinisikan. Hampir semua fungsi memiliki daftar parameter yang menyediakan cara untuk mengkomunikasikan informasi antar fungsi melalui pemanggilan fungsi. Parameter fungsi dipandang sebagai variabel lokal. Ketika sebuah fungsi dipanggil, argumen-argumen pada pemanggilan fungsi tersebut ditugaskan kepada parameter-parameter terkait pada definisi fungsi.


6.4 Definisi Fungsi
Setiap skrip yang telah disajikan sejauh ini terdiri-dari sederet statemen dan struktur kendali. Skrip tersebut dieksekusi saat penjelajah web memuat halaman web dan mengevaluasi bagian <head>. Sekarang, akan didiskusikan bagaimana Anda dapat menuliskan fungsi Anda sendiri dan memanggilnya di dalam sebuah skrip.

Fungsi Terdefinisi-Pengguna kuadrat
Perhatikan sebuah skrip (Gambar 6.1) yang menggunakan fungsi kuadrat untuk menghitung kuadrat atas integer-integer dari 1 sampai 10.

Statemen for pada baris 15-17 menghasilkan XHTML yang menampilkan hasil kuadrat atas integer-integer dari 1 sampai 10. Setiap iterasi loop akan menghitung kuadrat atas nilai sekarang dari variabel kendali x dan menampilkan hasil dengan menuliskan sebaris teks pada dokumen XHTML. Fungsi kuadrat dipanggil pada baris 17 dengan ekspresi kuadrat(x). Ketika kendali program meraih ekspresi ini, program akan memanggil fungsi kuadrat (yang didefinisikan pada baris 23-26). Sepasang kurung ( dan ) merepresentasikan operator pemanggilan fungsi, yang memiliki derajat keutamaan yang tinggi. Pada titik ini, program membuat sebuah salinan dari nilai x (argumen) dan kendali program beralih ke baris pertama dari fungsi kuadrat. Fungsi kuadrat menerima salinan nilai x dan menyimpannya di dalam parameter y. Kemudian kuadrat menghitung y * y. Hasil tersebut dikirimkan kembali (dikembalikan) ke titik pada baris 17 dimana kuadrat dipanggil. Baris 16-17 menyambung “Kuadrat atas “, nilai x, string “ adalah “, nilai balik oleh fungsi kuadrat, dan sebuah tag <br />, dan menuliskan baris teks tersebut pada dokumen XHTML. Proses ini diulangi sebanyak 10 kali.

Definisi atas fungsi kuadrat (baris 23-26) menunjukkan bahwa kuadrat mengharapkan sebuah parameter y. Fungsi kuadrat menggunakan nama ini di dalam tubuhnya untuk memanipulasi nilai yang dilewatkan kepada kuadrat dari baris 17. Statemen return pada kuadrat melewatkan hasil dari perhitungan y * y kembali kepada fungsi pemanggil. Perhatikan bahwa katakunci var tidak digunakan untuk mendeklarasikan variabel-variabel di dalam daftar parameter sebuth fungsi.
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
29
30
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<!-- Gambar 6.1: KuadratInt.html -->
<!-- Fungsi terdefinisi-pengguna kuadrat. -->
<html xmlns = "http://www.w3.org/1999/xhtml">
    <head>
        <title>Fungsi terdefinisi-pengguna kuadrat</title>
        <script type = "text/javascript">
            <!--
            document.writeln( "<h1>Kuadrat atas angka dari 1 sampai 10</h1>" );

            // kuadrat atas angka 1 sampai 10
            for ( var x = 1; x <= 10; x++ )
                document.writeln( "Kuadrat atas " + x + " adalah " +
                    kuadrat( x ) + "<br />" );

            // Definisi fungsi kuadrat berikut dieksekusi
            // hanya ketika fungsi secara eksplisit dipanggil.

            // definisi fungsi kuadrat
            function kuadrat( y )
            {
                return y * y;
            } // akhir fungsi kuadrat
            // -->
        </script>
    </head><body></body>
</html>



Gambar 6.1 Fungsi terdefinisi-pengguna kuadrat


Pada contoh ini, fungsi kuadrat ditempatkan di akhir skrip. Ketika statemen for berhenti, kendali program tidak beralih secara sekuensial ke fungsi kuadrat. Sebuah fungsi harus dipanggil secara eksplisit agar kode yang ada di dalam tubuhnya dieksekusi. Jadi, ketika statemen for berhenti pada contoh ini, skrip juga berhenti.

Format atas sebuah definisi fungsi adalah

function nama-fungsi( daftar-parameter )
{
    deklarasi dan statemen
}


Elemen nama-fungsi berupa sembarang pengenal yang valid. Elemen daftar-parameter merupakan sebuah daftar nama parameter (masing-masing parameter dipisahkan oleh koma) yang diterima oleh fungsi ketika ia dipanggil. Harus ada satu argumen pada pemanggilan fungsi untuk tiap parameter pada definisi fungsi. Jika sebuah fungsi tidak menerima nilai apapun, maka daftar-parameter menjadi kosong (yaitu, nama fungsi diikuti oleh sepasang kurung kosong). Elemen deklarasi dan statemen yang diapit oleh sepasang kurung kurawal merupakan tubuh fungsi.

Ada tiga cara dalam mengembalikan kendali program ke titik dimana sebuah fungsi dipanggil. Jika fungsi tidak menghasilkan nilai balik apapun, maka kendali program kembali ketika program meraih kurung kurawal penutup atau ketika statemen return; dieksekusi.

Jika fungsi menghasilkan sebuah nilai balik, maka statemen

return ekspresi;

akan mengembalikan nilai dari ekspresi kepada pemanggil. Ketika statemen return dieksekusi, kendali program kembali dengan segera ke titik dimana fungsi dipanggil.


Fungsi Terdefinisi-Pengguna maksimum
Skrip pada contoh selanjutnya (Gambar 6.2) menggunakan sebuah fungsi terdefinisi-pengguna, maksimum, untuk menentukan dan menghasilkan nilai balik berupa nilai terbesar dari tiga nilai pecahan.

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
29
30
31
32
33
34
35
36
37
38
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<!-- Gambar 6.2: maksimum.html -->
<!-- Fungsi terdefenisi-pengguna maksimum. -->
<html xmlns = "http://www.w3.org/1999/xhtml">
    <head>
        <title>Mencari Nilai Terbesar dari Tiga Nilai</title>
        <script type = "text/javascript">
            <!--
            var masukan1 = window.prompt( "Masukkan angka pertama", "0" );
            var masukan2 = window.prompt( "Masukkan angka kedua", "0" );
            var masukan3 = window.prompt( "Masukkan angka ketiga", "0" );

            var nilai1 = parseFloat( masukan1 );
            var nilai2 = parseFloat( masukan2 );
            var nilai2 = parseFloat( masukan3 );

            var nilaiMaks = maksimum( nilai1, nilai2, nilai3 );

            document.writeln( "Angka pertama: " + angka1 +
                "<br />Angka kedua: " + angka2 +
                "<br />Angka ketiga: " + angka3 +
                "<br />Nilai maksimum adalah: " + nilaiMaks );

            // definisi fungsi maksimum dipanggil dari baris 20
            function maksimum( x, y, z )
            {
                return Math.max( x, Math.max( y, z ) );
            } // akhir fungsi maksimum
            // -->
        </script>
    </head>
    <body>
        <p>Klik Refresh untuk menjalankan skrip kembali</p>
    </body>
</html>



Gambar 6.2 Fungsi terdefinisi-pengguna maksimum


Tiga nilai pecahan dimasukkan oleh pengguna melalui dialog prompt (baris 12-14). Baris 16-18 menggunakan fungsi parseFloat untuk mengkonversi string yang dimasukkan pengguna menjadi nilai pecahan. Statemen pada baris 20 melewatkan ketiga nilai pecahan tersebut kepada fungsi maksimum (didefinisikan pada baris 28-31), yang menentukan nilai terbesar dari ketiga nilai pecahan. Nilai ini dikembalikan kepada baris 20 melalui statemen return di dalam fungsi maksimum. Nilai balik yang dikembalikan ditugaskan kepada variabel nilaiMaks. Baris 22-25 menampilkan tiga nilai pecahan yang dimasukkan oleh pengguna dan nilaiMaks yang merupakan hasil perhitungan.

Perhatikan implementasi dari fungsi maksimum (baris 28-31). Baris pertama mengindikasikan bahwa nama fungsi adalah maksimum dan bahwa fungsi ini memiliki tiga parameter (x, y, dan z) untuk menyelesaikan tugasnya. Selain itu, tubuh fungsi memuat statemen yang menjadikan nilai terbesar dari ketiga nilai pecahan sebagai nilai balik, menggunakan dua pemanggilan terhadap metode max dari objek Math. Pertama-tama, metode Math.max dipanggil dengan nilai variabel y dan z untuk menentukan yang terbesar dari kedua nilai tersebut. Selanjutnya, nilai variabel x dan hasil dari pemanggilan pertama terhadap Math.max dilewatkan kepada metode Math.max. Terakhir, hasil dari pemanggilan kedua terhadap Math.max dikembalikan ke titik dimana maksimum dipanggil (baris 20). Statemen di dalam tubuh fungsi maksimum dieksekusi hanya dieksekusi ketika fungsi itu dipangil dari baris 20.


6.5 Pembangkitan Angka Acak
Sekarang akan disajikan sebuah aplikasi pemrograman yang populer, yaitu permainan dan simulasi. Pada bagian ini dan bagian berikutnya, akan dikembangkan sebuah program permainan yang mencakup beberapa fungsi. Program tersebut menggunakan beberapa statemen kendali yang telah dipelajari.

Adalah elemen peluang yang membuat banyak orang tertarik untuk menebak atau bermain judi. Elemen peluang dihasilkan melalui metode random dari objek Math. Ingat bahwa random dikatakan metode karena ia melekat dengan objek Math.

Perhatikan statemen berikut:

var nilaiAcak = Math.random();

Metode random membangkitkan sebuah nilai pecahan dari 0.0 sampai 1.0 (tidak termasuk 1.0). Jika random benar-benar menghasilkan nilai-nilai acak, maka setiap nilai dari 0.0 sampai 1.0 (tidak termasuk 1.0) akan memiliki peluang yang sama.

Rentang nilai yang dihasilkan secara langsung oleh random seringkali berbeda dari apa yang dibutuhkan oleh aplikasi. Sebagai contoh, sebuah program yang mensimulasikan pelemparan koin hanya akan memerlukan 0 untuk kepala dan 1 untuk ekor. Sebuah program yang mensimulasikan pelemparan sebuah dadu enam-muka hanya akan memerlukan integer-integer acak dalam rentang 1 sampai 6.

Untuk mendemonstrasikan metode random, akan dikembangkan sebuah program (Gambar 6.3) yang mensimulasikan 20 pelemparan terhadap sebuah dadu enam-sisi dan yang menampilkan nilai setiap lemparan. Anda akan menggunakan operator perkalian (*) dengan random sebagai berikut:

Math.floor( 1 + Math.random() * 6 )

Pertama-tama, ekspresi tersebut mengalikan hasil dari sebuah pemanggilan terhadap Math.random() dengan 6 untuk menghasilkan sebuah angka dalam rentang 0.0 sampai 6.0 (tidak termasuk 6.0). Ini disebut dengan penskalaan rentang angka acak. Selanjutnya, akan ditambahkan 1 pada hasil untuk menggeser rentang nilai agar menhasilkan sebuah angka dalam rentang 1.0 sampai 7.0 (tidak termasuk 7.0). Terakhir, akan digunakan metode Math.floor untuk membulatkan hasil ke bawah menjadi integer terdekat yang bernilai tidak lebih besar dari nilai argumen. Sebagai contoh, 1.75 akan dibulatkan menjadi 1. Gambar 6.3 menegaskan bahwa hasil yang didapatkan berada di dalam rentang 1 sampai 6.

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
29
30
31
32
33
34
35
36
37
38
39
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<!-- Gambar 6.3: RandomInt.html -->
<!-- Integer acak, penggeseran, dan penskalaan. -->
<html xmlns = "http://www.w3.org/1999/xhtml">
    <head>
        <title>Integer Acak Tergeser dan Terskala</title>
        <style type = "text/css">
            table { width: 50%;
            border: 1px solid gray;
            text-align: center }
        </style>
        <script type = "text/javascript">
            <!--
            var nilai

            document.writeln( "<table>" );
            document.writeln( "<caption>Integer Acak</caption><tr>" );

            for ( var i = 1; i <= 20; i++ )
            {
                nilai = Math.floor( 1 + Math.random() * 6 );
                document.writeln( "<td>" + nilai + "</td>" );

                // memulai baris tabel yang baru setiap 5 entri
                if ( i % 5 == 0 && i != 20 )
                    document.writeln( "</tr><tr>" );
            } // akhir for

            document.writeln( "</tr></table>" );
            // -->
        </script>
    </head>
    <body>
        <p>Klik Refresh untuk menjalankan skrip kembali</p>
    </body>
</html>





Gambar 6.3 Integer acak, penggeseran dan penskalaan


Untuk menunjukkan bahwa angka-angka tersebut memiliki peluang yang hampir sama, berikut akan disimulasikan 6000 pelemparan sebuah dadu dengan program pada Gambar 6.4. Setiap integer dari 1 sampai 6 memiliki kemunculan yang mendekati 1000 kali. Gunakan tombol Refresh (atau Reload) untuk mengeksekusi skrip kembali.

Seperti yang ditunjukkan pada keluaran program, Anda menggunakan metode random dari objek Math dan teknik penskalaan dan penggeseran dari contoh sebelumnya dalam mensimulasikan pelemparan sebuah dadu enam-sisi. Perhatikan bahwa Anda juga menggunakan beberapa statemen kendali dalam menentukan jumlah kemunculan setiap sisi dari dadu enam-sisi. Baris 12-17 mendeklarasikan dan menginisialisasi pencacah-pencacah (kounter-kounter) untuk menjejak jumlah kemunculan tiap sisi dari dadu enam-sisi. Statemen for pada baris 21-46 beriterasi sebanyak 6000 kali. Pada tiap iterasi loop, baris 23 menghasilkan sebuah nilai dari 1 sampai 6, yang disimpan di dalam muka. Statemen switch bersarang pada baris 25-45 menggunakan nilai muka yang dipilih secara acak sebagai ekspresi pengendalinya. Berdasarkan nilai muka, program menginkremen salah satu dari enam variabel pencacah pada tiap iterasi loop. Perhatikan bahwa tidak ada kasus default yang disediakan pada statemen switch ini, karena statemen pada baris 23 hanya menghasilkan nilai 1, 2, 3, 4, 5, dan 6. Pada contoh ini, kasus default tidak akan pernah dieksekusi.

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
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<!-- Gambar 6.4: LemparDadu.html -->
<!-- Pelemparan Sebuah Dadu Enam-Sisi 6000 Kali. -->
<html xmlns = "http://www.w3.org/1999/xhtml">
    <head>
        <title>Pelemparan Sebuah Dadu Enam-Sisi 6000 Kali</title>
        <script type = "text/javascript">
            <!--
            var frekuensi1 = 0;
            var frekuensi2 = 0;
            var frekuensi3 = 0;
            var frekuensi4 = 0;
            var frekuensi5 = 0;
            var frekuensi6 = 0;
            var muka;

            // melempar dadu 6000 kali dan mengakumulasi hasil
            for ( var lemparan = 1; lemparan <= 6000; lemparan++ )
            {
                muka = Math.floor( 1 + Math.random() * 6 );

                switch ( muka )
                {
                    case 1:
                        ++frekuensi1;
                        break;
                    case 2:
                        ++frekuensi2;
                        break;
                    case 3:
                        ++frekuensi3;
                        break;
                    case 4:
                        ++frekuensi4;
                        break;
                    case 5:
                        ++frekuensi5;
                        break;
                    case 6:
                        ++frekuensi6;
                        break;
                } // akhir switch
            } // akhir for

            document.writeln( "<table border = \"1\">" );
            document.writeln( "<thead><th>Muka</th>" +
                "<th>Frekuensi</th></thead>" );
            document.writeln( "<tbody><tr><td>1</td><td>" +
                frekuensi1 + "</td></tr>" );
            document.writeln( "<tr><td>2</td><td>" + frekuensi2 +
                "</td></tr>" );
            document.writeln( "<tr><td>3</td><td>" + frekuensi3 +
                "</td></tr>" );
            document.writeln( "<tr><td>4</td><td>" + frekuensi4 +
                "</td></tr>" );
            document.writeln( "<tr><td>5</td><td>" + frekuensi5 +
                "</td></tr>" );
            document.writeln( "<tr><td>6</td><td>" + frekuensi6 +
                "</td></tr></tbody></table>" );
            // -->
        </script>
    </head>
    <body>
        <p>Klik Refresh untuk menjalankan skrip kembali</p>
 </body>
</html>



Gambar 6.4 Pelemparan sebuah dadu enam-sisi sebanyak 6000 kali


Jalankan program beberapa kali, dan amati hasilnya. Perhatikan bahwa program menghasilkan angka-angka acak yang berbeda setiap kali skrip dievaluasi, sehingga hasilnya bervariasi.

Nilai-nilai yang dihasilkan metode random selalu berada di dalam rentang

0.0 ≤ Math.random() < 1.0

Anda telah mendemonstrasikan statemen

muka = Math.floor( 1 + Math.random() * 6 );

yang mensimulasikan pelemparan sebuah dadu enam-sisi. Statemen ini selalu menugaskan sebuah integer (secara acak) kepada variabel muka, dalam rentang . Perhatikan bahwa lebar dari rentang ini adalah 6, dan angka awal pada rentang adalah 1.


6.6 Contoh: Permainan Peluang
Salah satu permainan peluang yang populer adalah permaian dadu yang dikenal dengan “craps”, yang dimainkan di semua kasino. Aturan permainan ini sederhana:

Seorang pemain melempar dua dadu. Setiap dadu mempunyai enam sisi. Setiap sisi memuat 1, 2, 3, 4, 5, atau 6 spot. Setelah dadu berhenti (setelah dilempar), jumlah spot pada sisi samping (menghadap layar) dihitung. Jika hasil perjumlahan bernilai 7 atau 11 pada pelemparan pertama, maka pemain menang. Jika hasil perjumlahan bernilai 2, 3, atau 12 pada pelemparan pertama (disebut “craps”), maka pemain kalah. Jika hasil perjumlahan bernilai 4, 5, 6, 8, 9, atau 10 pada pelemparan pertama, maka penjumlahan tersebut menjadi poin bagi pemain. Untuk menang, pemain harus melanjutkan melempar dadu sampai pemain “mencetak poin”. Pemain kalah bila mendapatkan 7 sebelum ia mencetak poin.

Gambar 6.5 mensimulasikan permainan craps. Pemain harus melemparkan dua dadu pada pelemparan pertaman dan semua pelemparan berikutnya. Ketika Anda mengeksekusi skrip tersebut, Anda perlu mengkli tombol LemparDadu untuk memulai permainan. Sebuah pesan yang berada di bawah tombol LemparDadu menampilkan hasil permainan pada tiap lemparan.

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
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<!-- Gambar 6.5: Craps.html -->
<!-- Simulasi permainan craps. -->
<html xmlns = "http://www.w3.org/1999/xhtml">
    <head>
        <title>Program untuk mensimulasikan permainan Craps</title>
        <style type = "text/css">
            table { text-align: right }
            body { font-family: arial, sans-serif }
            div.red { color: red }
        </style>
        <script type = "text/javascript">
            <!--
            // variabel-variabel untuk menguji keadaan permainan
            var MENANG = 0;
            var KALAH = 1;
            var LANJUT_PELEMPARAN = 2;

            // variabel-variabel lain dalam program
            var lemparanPertama = true; // true jika pelemparan pertama
            var jumDadu = 0; // jumlah dadu
            var poinKu = 0; // poin jika tidak menang/kalah pada lemparan pertama
            var statusPermainan = LANJUT_PELEMPARAN; // permainan belum berakhir

            // memproses satu lemparan dadu
            function bermain()
            {
                // mendapatkan bidang poin
                var poin = document.getElementById( "bidangpoin" );

                // mendapatkan div status
                var statusDiv = document.getElementById( "status" );
                if ( lemparanPertama ) // lemparan pertama dadu
                {
                    jumDadu = lemparDadu();

                    switch ( jumDadu )
                    {
                        case 7: case 11: // menang pada lemparan pertama
                            statusPermainan = MENANG;
                            // menghapus bidang poin
                            poin.value = "";
                            break;
                        case 2: case 3: case 12: // kalah pada lemparan pertama
                            statusPermainan = KALAH;
                            // menghapus bidang poin
                            poin.value = "";
                            break;
                        default: // mengingat poin
                            statusPermainan = LANJUT_PELEMPARAN;
                            poinKu = jumDadu;
                            poin.value = poinKu;
                            lemparanPertama = false;
                    } // akhir switch
                } // akhir if
                else
                {
                    jumDadu = lemparDadu();

                    if ( jumDadu == poinKu ) // menang dengan mencetak poin
                        statusPermainan = MENANG;
                    else
                        if ( jumDadu == 7 ) // kalah dengan melempar 7
                            statusPermainan = KALAH;
                } // akhir else

                if ( statusPermainan == LANJUT_PELEMPARAN )
                    statusDiv.innerHTML = "Lempar Lagi";
                else
                {
                    if ( statusPermainan == MENANG )
                        statusDiv.innerHTML = "Pemain menang. " +
                        "Klik Lempar Dadu untuk bermain kembali.";
                    else
                        statusDiv.innerHTML = "Pemain kalah. " +
                            "Klik Lempar Dadu untuk bermain kembali.";

                    lemparanPertama = true;
                } // akhir else
            } // akhir fungsi bermain

            // melempar dadu
            function lemparDadu()
            {
                var dadu1;
                var dadu2;
                var jum;

                dadu1 = Math.floor( 1 + Math.random() * 6 );
                dadu2 = Math.floor( 1 + Math.random() * 6 );
                jum = dadu1 + dadu2;

                document.getElementById( "bidangdadu1" ).value = dadu1;
                document.getElementById( "bidangdadu2" ).value = dadu2;
                document.getElementById( "bidangjum" ).value = jum;

                return jum;
            } // akhir fungsi lemparDadu
            // -->
        </script>
    </head>
    <body>
        <form action = "">
            <table>
            <caption>Craps</caption>
            <tr><td>Dadu 1</td>
                <td><input id = "bidangdadu1" type = "text" />
                </td></tr>
            <tr><td>Dadu 2</td>
                <td><input id = "bidangdadu2" type = "text" />
                </td></tr>
            <tr><td>Jum</td>
                <td><input id = "bidangjum" type = "text" />
                </td></tr>
            <tr><td>Poin</td>
                <td><input id = "bidangpoin" type = "text" />
                </td></tr>
            <tr><td /><td><input type = "button" value = "Lempar Dadu"
                onclick = "bermain()" /></td></tr>
            </table>
            <div id = "status" class = "red">
                Klik tombol Lempar Dadu untuk bermain</div>
        </form>
    </body>
</html>



Gambar 6.5 Simulasi permainan Craps


Sampat saat ini, semua interaksi pengguna dengan skrip dilakukan melalui sebuah dialog prompt (dimana di dalamnya pengguna mengetikkan sebuah nilai masukan untuk program) atau melalui dialog alert (dimana di dalamnya pesan ditampilkan kepada pengguna). Meskipun kedua dialog ini merupakan cara yang valid dalam menerima masukan dari pengguna dan dalam menampilkan pesan, keduanya memiliki keterbatasan kapabilitas. Dialog prompt hanya dapat memperoleh satu nilai pada suatu waktu dari pengguna, dan dialog alert hanya dapat menampilkan satu pesan saja.


Formulir XHTML
Lebih sering, masukan jamak diterima dari pengguna sekaligus melalui sebuah formulir XHTML (XHTML form), dimana di dalamnya, misalnya, pengguna memasukkan informasi nama dan alamat atau program menampilkan banyak data sekaligus. Untuk memulai diskusi tentang antarmuka pengguna yang lebih kompleks, program ini menggunakan sebuah formulir XHTML dan konsep antarmuka pengguna yang baru, yaitu penanganan event GUI. Ini merupakan contoh pertama dimana di dalamnya JavaScript dieksekusi akibat merespon interaksi pengguna dengan sebuah komponen GUI pada formulir XHTML. Interaksi ini memicu event.

Sebelum kode skrip didiskusikan, akan didiskusikan terlebih dahulu mengenai elemen body pada dokumen XHTML (baris 105-126). Komponen-komponen GUI pada bagian ini digunakan secara ekstensif di dalam skrip.

Baris 106 memulai definisi atas sebuah elemen form XHTML. XHTML standar mensyaratkan bahwa setiap form harus memuat sebuah atribut action, tetapi karena formulir ini tidak menempatkan informasinya pada sebuah web server, string kosong (“”) digunakan.

Pada contoh ini, Anda telah memutuskan untuk menempatkan komponen-komponen GUI formulir di dalam elemen table XHTML, jadi baris 107 memulai definisi tabel XHTML. Baris 109-120 menciptakan empat baris tabel. Setiap baris memuat sebuah sel kiri dengan suatu label teks dan sebuah elemen input pada sel kanan.

Empat bidang input (baris 110, 113, 116, dan 119) diciptakan untuk menampilkan nilai dari dadu pertama, dadu kedua, penjumlahan dadu, dan nilai poin saat ini, jika ada. Atribut id masing-masing ditetapkan menjadi bidangdadu1, bidangdadu2, bidangjum, dan bidangpoin. Atribut id dapat dipakai untuk menerapkan beberapa style dari CSS dan untuk memampukan kode skrip merujuk ke sebuah elemen pada dokumen XHTML. Karena atribut id harus memiliki nilai unik, JavaScript dapat merujuk setiap elemen melalui atribut idnya. Akan dilihat bagaimana ini dilakukan.

Baris 121-122 menciptakan baris kelima dengan sebuah sel kosong di kolom kiri yang berada sebelum tombol Lempar Dadu. Atribut onclick mengindikasikan aksi yang akan dilakukan ketika pengguna dokumen XHTML mengklik tombol Lempar Dadu. Pada contoh ini, pengklikan tombol tersebut menyebabkan sebuah pemanggilan fungsi bermain.


Pemrograman Event-Driven
Gaya pemrograman ini dikenal sebagai pemrograman event-driven, dimana pengguna berinteraksi dengan sebuah komponen GUI. Skrip kemudian diberitahu akan terjadinya event dan memproses event tersebut. Interaksi pengguna dengan GUI “menyetir” program. Klik pada tombol dinamakan dengan event. Fungsi yang dipanggil ketika sebuah event terjadi dikenal sebagai fungsi penanganan-event atau event handler. Ketika sebuah event GUI terjadi pada suatu formulir, penjelajah web memanggil fungsi penanganan-event tertentu. Karena event harus diproses, setiap komponen GUI harus mengetahui fungsi penanganan-event yang mana yang akan dipanggil ketika event tertentu terjadi. Hampir semua komponen GUI XHTML memiliki beberapa jenis event. Model event akan dibahas secara detil pada Bab 11. Dengan menetapkan onclik = “bermain()” untuk tombol Lempar Dadu, Anda menginstruksikan kepada penjelajah web untuk mendengarkan setiap event (pengklikan tombol) untuk tombol tersebut. Hal ini meregistrasikan atau mendaftarkan fungsi penanganan-event (event handler) bagi komponen GUI tersebut, yang menyebabkan penjelajah web untuk mendengarkan event pengklikan tombol pada komponen itu. Jika tidak ada fungsi penanganan-event yang ditetapkan bagi tombol Lempar Dadu, maka skrip tidak akan merespon ketika pengguna menekan tombol tersebut.

Baris 123-125 mengakhiri elemen table dan form. Ditempatkan setelah tabel, sebuah elemen div diciptakan dengan atribut id,status”. Elemen ini akan diperbarui oleh skrip untuk menampilkan hasil dari tiap pelemparan kepada pengguna. Deklarasi style pada baris 13 akan mewarnai teks yang dimuat pada div ini.


Mendiskusikan Kode Skrip Permainan
Pemain dapat menang atau kalah pada lemparan pertama, atau menang atau kalah pada lemparan selanjutnya. Baris 18-20 menciptakan beberapa variabel yang mendefinisikan tiga keadaa permainan, yaitu permainan dimenangkan, permainan kalah, dan melanjutkan pelemparan dadu. Tidak seperti bahasa pemrograman lainnya, JavaScript tidak menyediakan mekanisme untuk mendefinisikan sebuah konstanta (sebuah variabel dengan nilai yang tidak bisa dimodifikasi). Karena alasan ini, Anda dapat menggunakan semua huruf besar untuk nama variabel, untuk mengindikasikan  bahwa Anda tidak berniat untuk memodifikasi nilainya.

Baris 23-26 mendeklarasikan beberapa variabel yang digunakan di keseluruhan skrip. Variabel lemparanPertama mengindikasikan apakah lempara berikutnya atas dadu merupakan lemparan pertama pada permainan sekarang. Variabel jumDadu menyimpan jumlah dadu dari lemparan terakhir. Variabel poinKu menyimpan poin jika pemain tidak menang atau kalah pada lemparan pertama. Variabel statusPermainan menjejak status permainan (MENANG, KALAH, LANJUT_PELEMPARAN).

Anda mendefinisikan sebuah fungsi lemparDadu (baris 86-101) untuk melemparkan dadu dan untuk menghitung dan menampikan penjumlahannya. Fungsi lemparDadu didefinisikan hanya sekali, tetapi dipanggil dari dua tempat di dalam program (baris 38 dan 61). Fungsi lemparDadu tidak memerlukan argumen, jadi ia mempunyai daftar parameter kosong. Fungsi lemparDadu menghasilkan penjumlahan atas dua dadu.

Pengguna mengklik tombol Lempar Dadu untuk melemparkan dadu. Aksi ini melibatkan fungsi bermain (baris 29-83) pada skrip. Baris 32 dan 35 menciptakan dua variabel baru dengan objek-objek yang merepresentasikan elemen-elemen pada dokumen XHTML menggunakan metode getElementById dari objek document. Metode getElemenById, jika diberikan sebuah id sebagai argumen, akan mencari elemen XHTML dengan atribut id yang cocok dan menghasilkan sebuah objek JavaScript yang merepresentasikan elemen tersebut. Baris 32 menyimpan sebuah objek yang merepresentasikan  elemen masukan bidangpoin (baris 119) di dalam variabel poin. Baris 35 memperoleh sebuah objek yang merepresentasikan status div dari baris 124.

Fungsi bermain memeriksa variabel lemparanPertama (baris 36) untuk menentukan apakah ia bernilai true atau false. Jika true, maka lemparan tersebut adalah lemparan pertama pada permainan. Baris 38 memanggil lemparDadu, yang mengambil dua angka acak dalam rentang 1 sampai 6, menampilkan nilai dari dadu pertama, nilai dari dadu kedua, dan penjumlahan atas dua dadu pada ketiga bidang teks pertama, dan menghasilkan penjumlahan dua dadu sebagai nilai balik. Setelah lemparan pertama (jika lemparanPertama bernilai false), statemen switch bersarang pada baris 40-57 menentukan apakah permainan telah dimenangkan atau apakah pemain telah kalah. Setelah lemparan pertama, jika permainan belum berakhir, jumDadu disimpan pada poinKu dan ditampilkan pada bidang teks poin di dalam formulir XHTML.


6.7 Contoh Lain: Pembangkit Citra Acak
Isi web yang berubah secara acak menambah efek dinamis pada sebuah halaman web. Pada contoh berikutnya, Anda akan membuat sebuah pembangkit citra acak, sebuah skrip yang menampilkan sebuah citra secara acak setiap kali halaman yang memuat skrip tersebut dijalankan kembali.

Agar skrip pada Gambar 6.6 dapat berfungsi secara tepat, direktori yang memuat file CitraAcak.html harus memuat tujuh citra dengan nama file integer (misalnya, 1.gif, 2.gif, ..., 7.gif). Halaman web yang memuat skrip ini akan menampilkan salah satu dari tujuh citra, dipilih secara acak, setiap kali halaman dijalankan kembali.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<!-- Gambar 6.6: CitraAcak.html -->
<!-- Pembangkitan citra acak menggunakan Math.random. -->
<html xmlns = "http://www.w3.org/1999/xhtml">
    <head>
        <title>Pembangkitan Citra Acak</title>
        <script type = "text/javascript">
            <!--
            document.write ( "<img src = \"" +
                Math.floor( 1 + Math.random() * 7 ) + ".gif\" />" );
            // -->
        </script>
    </head>
    <body>
        <p>Klik Refresh untuk menjalankan skrip ini kembali</p>
     </body>
</html>



Gambar 6.6 Pembangkitan citra acak menggunakan Math.random


Baris 12-13 secara acak memilih sebuah citra untuk ditampilkan pada halaman web. Statemen document.write ini menciptakan sebuah tag citra pada halaman web dengan atribut src untuk menetapkan sebuah integer acak dari 1 sampai 7, yang disambungkan dengan “.gif”. Jadi, skrip secara dinamis menetapkan sumber dari tag citra menjadi nama dari salah satu file citra pada direktori aktif.


6.8 Aturan Skop
Atribut variabel memuat nama, nilai, dan tipe data (misalnya, string, angka atau boolean). Anda juga menggunakan pengenal sebagai nama untuk fungsi terdefinisi-pengguna. Setiap pengenal pada sebuah program juga memiliki skop.

Skop sebuah pengenal untuk variabel atau fungsi adalah potongan program dimana di dalamnya pengenal dapat dikenali (direferensi). Variabel global atau variabel level-skrip yang dideklarasikan di dalam elemen head dapat diakses dari mana saja di dalam skrip dan dikatakan memiliki skop global. Jadi, setiap fungsi di dalam skrip dapat menggunakan variabel semacam itu.

Pengenal yang dideklarasikan di dalam sebuah fungsi memiliki skop fungsi (skop lokal) dan dapat dipakai hanya di dalam fungsi tersebut. Skop fungsi dimulai dari kurung kurawal pembuka ({) dari fungsi terkait dan berakhir di kurung kurawal penutup (}). Variabel lokal pada sebuah fungsi dan parameter fungsi memiliki skop fungsi. Jika variabel lokal di dalam sebuah fungsi memiliki nama sama dengan sebuah variabel global, maka variabel global tersembunyi atau tidak dikenali di dalam tubuh fungsi.

Skrip pada Gambar 6.7 mendemonstrasikan beberapa aturan skop yang melibatkan variabel global dan variabel lokal dengan nama sama. Contoh ini juga mendemonstrasikan event onload (Baris 52), yang memanggil sebuah fungsi penanangan-event (mulai) ketika <body> pada dokumen XHTML dieksekusi oleh penjelajah web.

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
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
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<!-- Gambar 6.7: Skop.html -->
<!-- Contoh aturan skop. -->
<html xmlns = "http://www.w3.org/1999/xhtml">
    <head>
        <title>Sebuah Aturan Skop</title>
        <script type = "text/javascript">
            <!--
            var x = 1; // variabel global
           
            function mulai()
            {
                var x = 5; // variabel lokal di dalam fungsi mulai

                document.writeln( "x lokal di dalam mulai adalah " + x );

                fungsiA(); // fungsiA memiliki x lokal
                fungsiB(); // fungsiB menggunakan variabel global x
                fungsiA(); // fungsiA menginisialisasi-ulang x lokal
                fungsiB(); // variabel global x mempertahankan nilainya

                document.writeln(
                    "<p>x lokal di dalam mulai adalah " + x + "</p>" );
            } // akhir fungsi mulai

            function fungsiA()
            {
                var x = 25; // diinisialisasi setiap kali
                            // fungsiA dipanggil

                document.writeln( "<p>x lokal di dalam fungsiA adalah " +
                    x + " setelah memasuki fungsiA" );
                ++x;
                document.writeln( "<br />x lokal di dalam fungsiA adalah " +
                    x + " sebelum keluar dari fungsiA" + "</p>" );
            } // akhir fungsiA

            function fungsiB()
            {
                document.writeln( "<p>variabel global x adalah " + x +
                    " pada saat memasuki fungsiB" );
                x *= 10;
                document.writeln( "<br />variabel global x adalah " +
                    x + " pada saat keluar dari fungsiB" + "</p>" );
            } // akhir fungsiB
            // -->
        </script>
    </head>
    <body onload = "mulai()"></body>
</html>



Gambar 6.7 Contoh penerapan aturan skop


Variabel global x (baris 12) dideklarasikan dan diinisialisasi dengan 1. Variabel global ini tersembunyi (tidak dapat diakses) dari sembarang blok (fungsi) yang mendeklarasikan sebuah variabel bernama x. Fungsi mulai (baris 14-27) mendeklarasikan sebuah variabel lokal x (baris 16) dan menginisialisasinya dengan 5. Variabel ini ditampilkan pada sebuah baris pada teks XHTML untuk menunjukkan bahwa variabel global x tidak dapat diakses di dalam mulai. Skrip mendefinisikan dua fungsi lain, fungsiA dan fungsiB, yang masing-masing tidak memerlukan argumen dan tidak menghasilkan nilai balik apapun. Setiap fungsi tersebut dipanggil dua kali dari fungsi mulai.

Fungsi fungsiA mendefinisikan variabel lokal x (baris 31) dan menginisialisasinya dengan 25. Ketika fungsiA dipanggil, variabel tersebut ditampilkan pada sebaris teks XHTML untuk menunjukkan bahwa variabel global x tidak dapat diakses di dalam fungsiA; kemudian variabel lokal itu diinkremen dan ditampilkan kembali pada sebaris teks XHTML sebelum fungsi tersebut keluar. Setiap kali fungsi ini dipanggil, variabel lokal x diciptakan-ulang dan diinisialisasi dengan 25.

Fungsi fungsiB tidak mendeklarasikan sembarang variabel lain. Oleh karena itu, ia mengakses variabel x, yaitu variabel global x. Ketika fungsiB dipanggil, variabel global itu ditampilkan pada sebaris teks XHTML, dikalikan dengan 10, dan ditampilkan kembali pada sebaris teks XHTML sebelum fungsi tersebut keluar. Ketika fungsiB dipanggil kembali, variabel global telah memiliki nilai termodifikasi, 10, yang kembali dikalikan dengan 10, dan 100 ditampilkan. Terakhir, program menampilkan kembali variabel lokal x di dalam mulai pada sebaris teks XHTML untuk menunjukkan bahwa tidak satupun pemanggilan fungsi yang memodifikasi nilai x di dalam mulai.


6.9 Rekursi
Berikut akan dituliskan sebuah program rekursif untuk melakukan perhitungan matematik populer, faktorial. Faktorial dari sebuah integer tak-negatif n, ditulis n!, adalah

n · (n – 1) · (n – 2) · … · 1

dimana 1! sama dengan 1 dan 0! didefinisikan sebagai 1. Sebagai contoh, 5! adalah perkalian dari 5 · 4 · 3 · 2 · 1, yang bernilai sama dengan 120.

Faktorial dari sebuah integer (angka pada contoh berikut) yang bernilai lebih dari atau sama dengan nol dapat dihitung secara iteratif (tak-rekursif) menggunakan sebuah statemen for, sebagai berikut:

var faktorial = 1;

for ( var kounter = angka; kounter >= 1; --kounter )
    faktorial *= kounter;

Definisi rekursif atas fungsi faktorial dicapai dengan mengamati relasi berikut:

n! = n · (n – 1)!

Sebagai contoh, 5! sama dengan 5 * 4!, seperti ditunjukkan dengan persamaan-persamaan berikut:

5! = 5 · 4 · 3 · 2 · 1
5! = 5 · (4 · 3 · 2 · 1)
5! = 5 · (4!)

Evaluasi terhadap 5! akan diproses seperti yang ditampilkan pada Gambar 6.8. Gambar 6.8a menunjukkan bagaimana beberapa pemanggilan rekursif secara beruntun dilakukan sampai 1! dievaluasi menjadi 1, yang menghentikan rekursi. Gambar 6.9b menunjukkan nilai-nilai balik dari tiap pemanggilan rekursif yang dikembalikan kepada pemanggilnya sampai nilai akhir dihitung.

Gambar 6.9 menggunakan rekursi untuk menghitung dan menampilkan faktorial integer dari 0 sampai 10. Fungsi rekursif faktorial pertama-tama menguji (baris 24) apakah kondisi bernilai true (yaitu, apakah angka bernilai kurang dari atau sama dengan 1). Jika ya, maka faktorial menghasilkan 1, dan tidak ada proses rekursi yang diperlukan. Jika angka bernilai lebih dari 1, maka baris 27 mengekspresikan permasalahan sebagai perkalian dari angka dan nilai balik dari sebuah pemanggilan rekursif atas faktorial (yang menghitung faktorial dari angka – 1).

Fungsi faktorial (baris 22-28) menerima sebagai argumennya nilai yang akan dihitung. Seperti yang dapat dilihat dari keluaran, nilai-nilai faktorial membesar dengan sangat cepat.



Gambar 6.8 Evaluasi rekursif atas 5!


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
29
30
31
32
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<!-- Gambar 6.9: UjiFaktorial.html -->
<!-- Perhitungan faktorial dengan fungsi rekursif -->
<html xmlns = "http://www.w3.org/1999/xhtml">
    <head>
        <title>Fungsi Faktorial Rekursif</title>
        <script type = "text/javascript">
            <!--
            document.writeln( "<h1>Faktorial dari 1 sampai 10</h1>" );
            document.writeln( "<table>" );

            for ( var i = 0; i <= 10; i++ )
                document.writeln( "<tr><td>" + i + "!</td><td>" +
                    faktorial( i ) + "</td></tr>" );

            document.writeln( "</table>" );

            // Definisi rekursif atas fungsi faktorial
            function faktorial( angka )
            {
                if ( angka <= 1 ) // kasus basis
                    return 1;
                else
                    return angka* faktorial( angka - 1 );
            } // akhir fungsi faktorial
            // -->
        </script>
    </head><body></body>
</html>
  


Gambar 6.9 Perhitungan faktorial dengan fungsi rekursif

























No comments:

Post a Comment