Halaman

Rabu, 01 Januari 2014

Kesalahan Logika Mengenai Hoisting di JavaScript

Kesalahan logika banyak macamnya dan salah satunya mengenai deklarasi dan inisialisasi variabel di JavaScript. Kesalahan ini diistilahkan dengan hoisting atau kesalahan yang terjadi akibat salah peletakan deklarasi variabel. Kesalahan ini sering membuat programmer web bingung mengapa hal ini bisa terjadi.

Dalam pemrograman JavaScript, kita biasanya dapat mendeklarasikan variabel bisa dimana saja dalam suatu lingkup (scope). Contohnya seperti ini:
<script>
  function getJenisFile(extFile) {
    extFile = extFile.toLowerCase();
    
    if (extFile === ".cpp") {
      jenisFile = "C++";
    }
    else if (extFile === ".js") {
      jenisFile = "JavaScript";
    }
    else if (extFile === ".py") {
      jenisFile = "Python";
    }
    else {
      jenisFile = "Tidak terdefinisi";
    }
    
    var jenisFile; // deklarasi baru dilakukan
    alert(jenisFile);
  }
  
  // outputnya: Tidak terdefinisi
  getJenisFile('.java');
</script>

Berdasarkan sintaks di atas maka dapat dilihat bahwa variabel jenisFile diinisialisasi terlebih dahulu dalam blok if-else kemudian baru dideklarasikan atau dengan kata lain suatu variabel dapat diinisialisasi dahulu baru kemudian dideklarasikan. Mungkin Anda akan bertanya apakah terjadi error? Ternyata tidak terjadi error apapun dan saya sudah memeriksanya melalui tab Console di Firebug. Ini menandakan bahwa JavaScript membolehkan bentuk inisialisasi dan deklarasi seperti dalam bentuk di atas.

Tentu saja bentuk seperti di atas sebaiknya dihindari karena rentan terhadap bugs. Salah satu bugs-nya adalah jika Anda menggunakan variabel global dengan nama yang sama seperti variabel lokal yang dipakai dalam suatu fungsi maka variabel tersebut menjadi bernilai undefined. Saya ubah sedikit sintaks di atas menjadi:
<script>
  // ditambahkan variabel global
  var jenisFile = "Tidak terdefinisi";
  
  function getJenisFile(extFile) {
    extFile = extFile.toLowerCase();
    
    if (extFile === ".cpp") {
      jenisFile = "C++";
    }
    else if (extFile === ".js") {
      jenisFile = "JavaScript";
    }
    else if (extFile === ".py") {
      jenisFile = "Python";
    }
    // blok else dihapus
    
    // urutan dibalik
    alert(jenisFile);
    var jenisFile; // deklarasi baru dilakukan
  }
  
  // outputnya: undefined
  getJenisFile('.java');
</script>

Yang saya ubah dari kode di atas adalah:
1. Ditambahkannya variabel global yang memiliki nama yang sama dengan nama variabel lokal yaitu jenisFile. Variabel global ini saya inisialisasi dengan string: "Tidak terdefinisi".
2. Dihapuskannya blok else dan nilai defaultnya saya tuliskan pada deklarasi (sekaligus inisialisasi) variabel global jenisFile.
3. Kemudian terjadi perubahan urutan penulisan statemen fungsi alert() dan deklarasi variabel lokal jenisFile.

Berdasarkan perubahan kode di atas, mungkin Anda berpikir bahwa program akan menampilkan tulisan "Tidak terdefinisi". Tapi kenyataannya tidak begitu, justru nilai undefined yang ditampilkan. Mengapa terjadi demikian? Karena JavaScript menginterpretasikan bahwa deklarasi variabel lokal jenisFile diletakan paling atas sendiri dalam lingkup fungsi getJenisFile(). Sehingga JavaScript akan merubah kodenya menjadi:
<script>
  var jenisFile = "Tidak terdefinisi"; 
  
  function getJenisFile(extFile) {
    // secara implisit JavaScript memindahkan deklarasi variabel di awal scope
    var jenisFile;
    extFile = extFile.toLowerCase();
    
    // ... kode lainnya
    
    alert(jenisFile);
  }
  
  // outputnya: undefined
  getJenisFile('.java');
</script>

Sehingga jelaslah bahwa variabel jenisFile dalam lingkup fungsi getJenisFile() adalah milik variabel lokal yang baru dideklarasikan tapi belum diinisialisasi. Hal inilah yang dinamakan hoisting yang menyebabkan kesalahan logika. Berdasarkan kesimpulan ini maka sangat disarankan agar mendeklarasikan variabel JavaScript di urutan paling awal baik di dalam blok suatu fungsi atau tidak dan gunakanlah keyword var saat mendeklarasikannya. Jika memungkinkan variabel tersebut langsung diinisialisasi saat Anda mendeklarasikannya.

Untuk keperluan debugging, sangat disarankan Anda menggunakan tools atau plugins seperti Firebug di web browser Mozilla Firefox atau Chrome Developer Tools (CDT) di web browser Google Chrome/Chromium. Lihatlah dijendela Console-nya apakah terjadi kesalahan atau tidak. Tools ini sangat membantu Anda saat membuat aplikasi web. Sekian dan terima kasih...

© 2014 husnanlabs.blogspot.com

Tidak ada komentar:

Posting Komentar