Phân biệt rõ ràng
| Khái niệm | Undeclared (Chưa khai báo) | Undefined (Chưa định nghĩa) |
| Định nghĩa | Biến không tồn tại (chưa dùng var/let/const) | Biến đã khai báo nhưng chưa gán giá trị |
| Kiểu typeof | ReferenceError (throw error) | 'undefined' |
| Kiểm tra | try/catch hoặc 'name' in window | === undefined hoặc typeof === 'undefined' |
| Ví dụ | console.log(x) (x chưa khai báo) | let y; console.log(y) |
Ví dụ minh họa
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Undeclared vs Undefined</title>
<style>
body { font-family: 'Segoe UI', sans-serif; padding: 20px; }
.result { font-size: 16px; font-weight: 500; color: #6a1b9a; margin: 15px 0; padding: 15px; background: #f3e5f5; border-radius: 4px; white-space: pre-wrap; }
button { padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }
</style>
</head>
<body>
<h1>Undeclared vs Undefined</h1>
<div class="result" id="result1"></div>
<div class="result" id="result2"></div>
<button id="btn">KIỂM TRA</button>
<h3>Nhấn nút để truy cập biến undeclared và undefined</h3>
<script>
const btnEle = document.getElementById('btn');
const resEle1 = document.getElementById('result1');
const resEle2 = document.getElementById('result2');
let a; // Khai báo nhưng không gán giá trị -> undefined
// b không khai báo -> undeclared
btnEle.addEventListener('click', () => {
// Undefined
resEle1.textContent = `Biến a (khai báo, không gán): ${a}\n`;
resEle1.textContent += `typeof a: ${typeof a}\n`;
resEle1.textContent += `a === undefined: ${a === undefined}\n`;
// Undeclared - phải dùng try/catch
try {
resEle2.textContent = `Biến b (chưa khai báo): ${b}`;
} catch (err) {
resEle2.textContent = `Lỗi truy cập b: ${err.name}: ${err.message}\n`;
resEle2.textContent += `typeof b: ${typeof b}`; // "undefined" - typeof không throw!
}
});
</script>
</body>
</html>
Kết quả
Biến a (khai báo, không gán): undefined
typeof a: undefined
a === undefined: true
Lỗi truy cập b: ReferenceError: b is not defined
typeof b: undefined
Lưu ý quan trọng về typeof
typeof undeclaredVar; // "undefined" - KHÔNG THROW ERROR!
typeof declaredButUndefined; // "undefined"
// Do đó, typeof an toàn để check tồn tại
if (typeof someVar !== 'undefined') {
// someVar tồn tại (khai báo hoặc global)
}
Cách kiểm tra an toàn
1. Kiểm tra undeclared (global)
'variableName' in window // true nếu global variable tồn tại
window.hasOwnProperty('variableName')
2. Kiểm tra undefined
let x;
x === undefined // true
typeof x === 'undefined' // true (an toàn hơn, không throw nếu x undeclared)
3. Default parameter / Nullish coalescing
function foo(param = 'default') { ... } // ES6 default param
const value = possiblyUndefined ?? 'default'; // ES2020 nullish coalescing
const value = possiblyUndefined || 'default'; // Falsy values (0, '', false) cũng bị ghi đè
Best Practice
- Luôn khai báo biến với
const/let trước khi dùng
- Dùng
typeof để check an toàn biến có thể không tồn tại
- Dùng default parameters thay vì check undefined trong function
- ESLint rule:
no-undef, no-unused-vars