Trong JavaScript, việc đặt toán tử unary plus (+) trước định nghĩa hàm (function) nhằm mục đích buộc trình phân tích (parser) xử lý đoạn code đó như một "biểu thức" (expression) thay vì "khẳng định" (statement). Điều này cho phép gọi thực thi hàm ngay lập tức (IIFE - Immediately Invoked Function Expression).
Ví dụ cơ bản
+function() { alert("Demo!"); }();
// Tương đương:
(function() { alert("Demo!"); })();
// Hoặc:
(function() { alert("Demo!"); }());
Tại sao cần làm vậy?
Trong JavaScript, từ khóa function ở đầu câu lệnh được hiểu là Function Declaration (Khai báo hàm) - bắt buộc phải có tên hàm và không thể gọi ngay. Để biến nó thành Function Expression (Biểu thức hàm), ta cần một toán tử đơn mục (unary operator) đứng trước: +, -, !, ~, hoặc bao quanh bằng cặp ngoặc đơn ( ).
Các toán tử unary khác cũng đạt hiệu quả tương tự
!function() { console.log("Hi"); }();
-function() { console.log("Hi"); }();
~function() { console.log("Hi"); }();
void function() { console.log("Hi"); }();
So sánh các cách viết IIFE phổ biến
| Cú pháp | Ưu điểm | Nhược điểm |
|---|---|---|
(function(){ ... })() | Phổ biến nhất, dễ đọc, chuẩn Crockford | Cần cặp ngoặc bao ngoài |
(function(){ ... }()) | Tương tự, đóng ngoặc trong | Ít phổ biến hơn |
+function(){ ... }() | Ngắn gọn, tiết kiệm 1 byte (minify) | Ít quen thuộc, có thể gây nhầm lẫn với ép kiểu số |
!function(){ ... }() | Ngắn gọn, thường dùng trong thư viện (jQuery, Bootstrap) | Trả về giá trị boolean (phủ định kết quả hàm) |
Lưu ý quan trọng
- Giá trị trả về:
+function(){}()sẽ trả về kết quả của hàm được ép kiểu thành Number (do toán tử+).!function(){}()trả về boolean (phủ định). Cặp ngoặc(function(){})()trả về giá trị gốc của hàm. - Dấu chấm phẩy (;): Luôn kết thúc IIFE bằng
;nếu dòng code tiếp theo bắt đầu bằng(,[,/,+,-để tránh lỗi ASI (Automatic Semicolon Insertion). - Module hiện đại (ES6+): Nên dùng
import/exportvà module scope thay vì IIFE để quản lý namespace.
Khi nào nên dùng?
- Code cũ (ES5), thư viện cần đóng gói biến cục bộ, tránh ô nhiễm global scope.
- Khởi tạo một lần (initialization), cấu hình plugin, polyfill.
- Minification (nén code):
+function(){}()ngắn hơn(function(){})()1 ký tự.
Tóm lại: Dấu + (hoặc !, -, ~, void, ngoặc đơn) trước function chuyển "Function Declaration" thành "Function Expression" để có thể gọi ngay (IIFE), tạo scope riêng, tránh xung đột biến toàn cục.