Để kiểm tra xem một hàm đã được định nghĩa (khai báo) trong JavaScript hay chưa, cách chuẩn và an toàn nhất là sử dụng toán tử typeof so sánh với chuỗi "function".
Cách 1: typeof - Khuyên dùng (An toàn, chuẩn)
if (typeof myFunction === "function") {
// Hàm myFunction đã được định nghĩa, có thể gọi an toàn
myFunction();
} else {
console.log("Hàm myFunction CHƯA được định nghĩa");
}
Ưu điểm: Không gây lỗi ReferenceError nếu hàm chưa tồn tại. Hoạt động với cả Function Declaration và Function Expression.
Cách 2: Kiểm tra trong object (window, module, namespace)
Nếu hàm là phương thức của một object (namespace):
// Kiểm tra method của object
if (typeof MyNamespace.myMethod === "function") { ... }
// Kiểm tra global function (trên trình duyệt)
if (typeof window.myGlobalFunc === "function") { ... }
Cách 3: try...catch (Ít dùng, cho trường hợp đặc biệt)
try {
myFunction(); // Gọi thử
// Nếu không lỗi -> hàm tồn tại
} catch (e) {
if (e instanceof ReferenceError) {
console.log("Hàm không tồn tại");
} else {
throw e; // Lỗi khác
}
}
Nhược điểm: Thực thi hàm (có thể gây side effect), chậm hơn, code rối.
❌ CÁCH KHÔNG NÊN DÙNG
// SAI: Gây ReferenceError nếu hàm chưa khai báo
if (myFunction) { ... }
// SAI: typeof myFunction === "undefined" (hàm tồn tại nhưng giá trị undefined - hiếm)
if (typeof myFunction !== "undefined") { ... } // Rủi ro nhầm lẫn
Ví dụ hoàn chỉnh
<!DOCTYPE html>
<html>
<body>
<script>
// 1. Hàm được khai báo bình thường (Function Declaration)
function sayHello() {
alert("Xin chào!");
}
// 2. Kiểm tra an toàn trước khi gọi
var funcName = "sayHello";
// Cách tốt nhất: typeof window[funcName] === "function"
if (typeof window[funcName] === "function") {
window[funcName](); // Gọi động an toàn
} else {
console.log("Hàm " + funcName + " không tồn tại");
}
// 3. Kiểm tra hàm không tồn tại
if (typeof nonExistentFunc === "function") {
nonExistentFunc();
} else {
console.log("Hàm nonExistentFunc chưa định nghĩa"); // Chạy nhánh này
}
</script>
</body>
</html>
Tóm tắt
| Cách kiểm tra | An toàn? | Khuyên dùng? | Ghi chú |
|---|---|---|---|
typeof funcName === "function" | ✅ Có | ✅ CHUẨN | Không gây lỗi, đúng ngữ nghĩa |
typeof obj.method === "function" | ✅ Có | ✅ Tốt | Cho method trong object/namespace |
funcName !== undefined | ❌ Không (ReferenceError) | ❌ Không | Gây crash nếu chưa khai báo |
try { func() } catch... | ⚠️ Có | ❌ Không | Thực thi hàm, chậm, rối |
Kết luận: Luôn dùng typeof tên_hàm === "function" để kiểm tra an toàn, chuẩn xác, không gây lỗi runtime.