BAB 21 — Execution Context & Hoisting: Memahami Cara JavaScript Mengeksekusi Kode

BAB 21 — Execution Context & Hoisting: Memahami Cara JavaScript Mengeksekusi Kode

Execution context dan hoisting adalah konsep fundamental JavaScript yang menentukan bagaimana kode dieksekusi, variabel diinisialisasi, dan fungsi dipanggil. Memahami hal ini membantu developer menghindari bug yang sulit ditangani dan menulis kode lebih aman.


1. Creation Phase vs Execution Phase

JavaScript mengeksekusi kode melalui dua fase utama:

1.1 Creation Phase (Memory Allocation)

  • Dibuat variable object, scope chain, dan this untuk konteks eksekusi.
  • Variabel diinisialisasi:
    • varundefined
    • let / consttemporal dead zone (TDZ)
  • Fungsi dideklarasikan → fully hoisted

1.2 Execution Phase

  • Kode dijalankan baris per baris.
  • Variabel diassign dengan nilai aktual.
  • Fungsi dieksekusi saat dipanggil.

Contoh sederhana:

console.log(a); // undefined
// console.log(b); // ReferenceError (TDZ)
var a = 10;
let b = 20;

Insight:

  • var dihoist → ada di memory sebagai undefined.
  • let dan const → aman karena TDZ, tidak bisa diakses sebelum deklarasi.

2. Global Execution Context

  • Terbentuk saat script pertama dijalankan.
  • Membuat global object (window di browser, global di Node.js).
  • this di global context → mengacu ke global object (di strict mode → undefined).
var a = 1;
let b = 2;
console.log(this.a); // 1
console.log(this.b); // undefined

Insight:

  • Global context → semua variabel var menjadi properti global, let/const tidak.
  • Menggunakan let/const di global → lebih aman untuk menghindari konflik.

3. Function Execution Context

  • Setiap pemanggilan fungsi menciptakan function execution context baru.
  • Terdiri dari:
    1. Variable object (VO) → menyimpan parameter, variabel lokal, dan fungsi.
    2. Scope chain → akses variabel di parent context.
    3. this binding → menentukan konteks pemanggilan.
function greet(name){
    var msg = "Hello " + name;
    console.log(msg);
}
greet("Alice");

Insight:

  • Variabel msg hanya ada di dalam function → function scope.
  • Function context memungkinkan nested function dan closure.

4. Lexical Environment

Lexical environment adalah struktur internal yang menyimpan variabel dan function scope.

  • Terdiri dari:
    1. Environment record → menyimpan variabel, parameter, dan fungsi.
    2. Reference ke outer lexical environment → membentuk scope chain.

Contoh closure:

function outer(){
    let outerVar = "Halo";
    return function inner(){
        console.log(outerVar);
    }
}
const fn = outer();
fn(); // Halo

Insight:

  • Inner function memiliki akses ke lexical environment parent → dasar closure.
  • Lexical environment memengaruhi hoisting, scope, dan closure.

5. Hoisting pada var / let / const

5.1 Hoisting var

console.log(a); // undefined
var a = 10;
  • Variabel dihoist → ada di memory tapi belum assign.

5.2 Hoisting let & const

// console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 20;

// console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 30;
  • Temporal Dead Zone (TDZ) → tidak bisa diakses sebelum deklarasi.
  • Membuat kode lebih predictable dan aman.

6. Mengapa let/const Lebih Aman

  1. Mencegah akses sebelum deklarasi
    • ReferenceError lebih aman daripada undefined yang bisa menimbulkan bug.
  2. Block scope
    • Variabel hanya hidup di dalam block {} → mencegah konflik dengan global atau outer scope.
  3. Konstanta untuk keamanan
    • const memastikan nilai tidak bisa di-reassign → aman untuk konfigurasi, function reference, dan constant values.
  4. Membantu debugging & maintainability
    • Lebih mudah melacak variabel, menghindari perilaku tidak terduga.

7. Praktik Terbaik

  • Gunakan const sebagai default.
  • Gunakan let jika nilainya akan berubah.
  • Hindari var → kecuali legacy code.
  • Pahami scope chain dan closure untuk menulis function modular dan aman.
  • Gunakan TDZ awareness untuk menghindari ReferenceError di kode asynchronous.

8. Kesimpulan

  • JavaScript mengeksekusi kode melalui creation phase & execution phase.
  • Global vs function execution context → menentukan scope variabel dan this.
  • Lexical environment → menyimpan variabel, function, dan reference ke parent scope → dasar closure.
  • Hoisting → var dihoist dengan undefined, let/const → TDZ → lebih aman.
  • Menggunakan let/const → praktik modern untuk kode lebih aman, predictable, dan maintainable.

💡 Insight: Memahami execution context, hoisting, dan lexical environment adalah kunci menguasai debugging, closure, dan async behavior di JavaScript.