Scope dan closure adalah konsep fundamental JavaScript yang menentukan kehidupan variabel, fungsi, dan akses antar lingkup. Memahami hal ini membantu developer menulis kode yang lebih modular, aman, dan reusable.
Contents
1. Block Scope
- Block scope terbentuk di dalam
{}, berlaku untukletdanconst. - Variabel
vartidak memiliki block scope, hanya function/global scope.
{
let a = 10;
const b = 20;
var c = 30;
console.log(a, b, c); // 10 20 30
}
console.log(c); // 30 → var tidak block scoped
// console.log(a); // ReferenceError
// console.log(b); // ReferenceError
Insight:
- Gunakan
let/constuntuk menghindari kebocoran variabel di luar block.
2. Function Scope
- Variabel yang dideklarasikan dengan
var,let, atauconstdi dalam function hanya hidup di function tersebut.
function greet() {
var a = 10;
let b = 20;
const c = 30;
console.log(a, b, c);
}
greet();
// console.log(a); // ReferenceError
- Function scope → dasar encapsulation dan modular function.
3. Lexical Scope
- Lexical scope → scope ditentukan berdasarkan lokasi penulisan kode, bukan eksekusi.
- Inner function bisa mengakses variabel di outer function.
function outer() {
let outerVar = "Halo";
function inner() {
console.log(outerVar);
}
inner();
}
outer(); // Halo
Insight:
- Lexical scope → dasar closure.
- Variabel parent tetap bisa diakses walaupun inner function dieksekusi di luar context asalnya (jika closure terbentuk).
4. Closure yang Sebenarnya
- Closure terjadi saat inner function masih mengakses variabel outer function setelah outer function selesai dieksekusi.
function makeCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
Penjelasan:
counttetap tersimpan dalam lexical environment meskimakeCounter()sudah selesai.- Closure memungkinkan state privat di dalam function.
5. Real-World Use Case Closure
5.1 Private State
function BankAccount(initialBalance) {
let balance = initialBalance;
return {
deposit(amount) { balance += amount; },
withdraw(amount) { balance -= amount; },
getBalance() { return balance; }
};
}
const account = BankAccount(1000);
account.deposit(500);
console.log(account.getBalance()); // 1500
// balance tidak bisa diakses langsung → aman
5.2 Function Factory
function multiplier(factor) {
return function(number) {
return number * factor;
};
}
const double = multiplier(2);
const triple = multiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
5.3 Event Handler dengan Closure
for (let i = 1; i <= 3; i++) {
setTimeout(() => {
console.log(`Nomor: ${i}`);
}, 1000);
}
// Output: 1 2 3 → menggunakan let untuk block scope & closure
Insight:
- Closure → sangat berguna untuk private data, callback, factory function, dan module pattern.
6. Praktik Terbaik Scope & Closures
- Gunakan block scope (
let/const) agar variabel tidak bocor ke luar block. - Gunakan function scope untuk modularisasi kode.
- Manfaatkan closure untuk state privat dan encapsulation.
- Hindari closure berlebihan yang menyebabkan memory leak.
- Gunakan lexical scope untuk callback, event listener, dan asynchronous function.
7. Kesimpulan
- Block scope → terbatas pada
{}→ aman untuk variabel sementara. - Function scope → variabel hanya hidup di function → dasar encapsulation.
- Lexical scope → scope ditentukan saat kode ditulis, bukan dijalankan → dasar closure.
- Closure → inner function bisa mengakses variabel outer function setelah outer selesai dieksekusi → memungkinkan private state.
- Praktik closure → state management, factory function, event handling, module pattern.
💡 Insight: Memahami scope & closures adalah kunci menulis JavaScript modular, aman, dan efisien, serta dasar untuk OOP, functional programming, dan advanced asynchronous patterns.