Monday, November 26, 2018

Pengalaman yang menakutkan...


Setiap orang ada pengalaman menakutkan. Saya juga tak terlepas melalui pengalaman ini.

Baru-baru ini saya berjaga malam untuk menyiapkan satu projek menggunakan Javascript. Sedang saya leka menulis atur cara ini, saya ternampak suatu benda yang sangat pelik. Saya pun cuba teliti betul-betul. Yalah, mana tahu saya tersalah tengok. Berulang kali saya periksa, rasanya macam mustahil terjadi perkara sedemikian. Selalunya tak akan muncul. Tapi yang ni betul-betul lain.


sumber foto: internet

Seram giler


Perhatikan kod aturcara Javascript di bawah:

function 
index2QuestionId( index ) {
    return 'q' + ( index + 1 );   
}

Operator + dalam Javascript boleh digunakan untuk operasi aritmetik (cth. 1+1=2) dan operasi pencantuman (concatenation) rentetan cth. "q" + 1 = "q1". Penentuan operasi akan dibuat secara automatik oleh penterjemah Javascript.

Fungsi Javascript di atas sepatutnya membina rentetan (string) berbentuk 'q1' (index=0), 'q29' (index=28) dsb. Parameter index sepatutnya menerima nilai integer untuk indeks suatu tatasusunan (array, yang bermula dari 0). Apa yang pelik? Nampak biasa saja kan? 

Tapi bukan bagi Javascript. Jika fungsi di atas dipanggil,


index2QuestionId(0);     // oops! return 'q01'??
index2QuestionId(28);    // oops! return 'q281'??

Kod tu saya rasa betul! Kenapa hasilnya salah? Ni yang jadi seram ni.

Setelah berhempas pulas debug dengan menggunakan Chrome developer tool (kemudianlah saya cerita pasal tool ni) akhirnya saya dapat kesan punca masalah dari fungsi ini dan kenapa ia berlaku.

Penjelasan


Penentuan operasi akan dibuat secara automatik oleh penterjemah Javascript. Ini bahayanya. Tujuannya memudahkan pengatur cara tetapi berisiko. Dalam contoh fungsi di atas, apa yang dibuat ialah (andaikan index=0),

=> 'q' + ( index + 1 )
=> 'q' + ( '0' + 1 )
=> 'q' + ( '01' )
=> 'q01'

Dalam kes ini index diterjemah sebagai string! (sepatutnya integer, 0 + 1 = 1) oleh penterjemah (bijak la sangat...)

Ini yang saya kata menakutkan, sebab tindakan penterjemah sebegini memang tak dijangka, dan susah nak dikesan.

Rasionalnya dalam kesilapan di atas, penterjemah tak ada cara menentukan parameter yang diberi ialah berjenis integer sebab bahasa Javascript tidak menggunakan penanda jenis data atau pemboleh ubah (bahasa Java atau C ada int, float, char dsb.). Jadi penterjemah cuba buat tekaan (dan tersilap).

Untuk memperbaiki masalah ini (memastikan penterjemah buat tekaan yang betul), boleh dilakukan dengan 2 cara seperti berikut:

CARA 1 - asingkan operasi untuk jenis data yang berbeza.

function 
index2QuestionId( index ) {
     var x = index + 1;      // aritmetik
     return 'q' + x;         // cantum
}

CARA 2 - jelaskan pada penterjemah operasi yang diperlukan (cth. parseInt() hasilkan integer, jadi dapat jelaskan pada penterjemah pembolehubah yang nak diguna ialah jenis integer)

function 
index2QuestionId( index ) {
     return 'q' + ( parseInt(index) + 1);
}

Kedua-dua cara ini akan hasilkan output yang betul seperti berikut

index2QuestionId(0);     // return 'q1'
index2QuestionId(28);    // return 'q29'

Bila dapat kesan punca kesilapan, dan tahu penyelesaiannya, barulah lega sikit.

Semoga perkongsian pengalaman menakutkan ini dapat memberi manfaat.
Jadi tuan-tuan, bila mengaturcara dengan Javascript berhati-hatilah.

Jangan biarkan diri anda diselubungi misteri...

No comments:

Post a Comment