IIFE là hàm được định nghĩa và gọi ngay lập tức.
javascript
;(function () {
const secret = 42 // không lọt ra ngoài
console.log(secret)
})()
;(() => {
// dạng arrow
})()
;(async () => {
await init() // dùng await ở cấp cao nhất khi chưa có top-level await
})()Cặp ngoặc bọc ngoài là bắt buộc: nó biến function declaration thành function expression, để có thể gọi ngay.
Trước ES6, JavaScript chỉ có function scope — IIFE là cách duy nhất để tạo phạm vi riêng. Mẫu module cổ điển dựa hoàn toàn vào nó:
javascript
const Counter = (function () {
let count = 0 // private thật sự
return {
inc() { return ++count },
get value() { return count },
}
})()
Counter.count // undefined — không truy cập được từ ngoàiNgày nay let/const cho block scope và ES module cho scope theo file, nên nhu cầu giảm hẳn. Nhưng IIFE vẫn dùng khi cần chạy async ngay trong môi trường chưa hỗ trợ top-level await, và xuất hiện dày đặc trong bundle đã build.
Lưu ý: thiếu dấu ; ở dòng trước khi bắt đầu bằng ( sẽ khiến JS hiểu là lời gọi hàm của dòng trên — lỗi khó thấy. Đó là lý do nhiều code base viết ;(function(){...})().