JavaScript có nhiều cách kiểm tra Array. Cách chuẩn và khuyến nghị nhất là Array.isArray() (ES5).
1. Array.isArray() – Chuẩn, chính xác, Cross-realm ✅
Array.isArray([]); // true
Array.isArray([1,2,3]); // true
Array.isArray(new Array()); // true
Array.isArray("string"); // false
Array.isArray({}); // false
Array.isArray(null); // false
Array.isArray(undefined); // false
Array.isArray({ length: 1 }); // false (array-like, không phải array)
- Hoạt động đúng qua iframe/window boundaries (cross-realm).
- Trả về boolean thuần túy.
- Hiệu năng tốt.
2. instanceof Array – Cũ, có vấn đề Cross-realm ⚠️
[] instanceof Array; // true
// ❌ VẤN ĐỀ: Trong iframe
// iframe.contentWindow.Array !== window.Array
// [] instanceof iframe.contentWindow.Array → false (nhưng là array thật)
3. Object.prototype.toString.call() – Polyfill cũ, chính xác ✅
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call("string"); // "[object String]"
// Helper function
function isArray(obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
}
4. constructor property – Không tin cậy ❌
[].constructor === Array; // true
// ❌ Có thể bị ghi đè: arr.constructor = Object;
So sánh
| Phương pháp | Cross-realm | Hiệu năng | Độ tin cậy | Khuyến nghị |
|---|---|---|---|---|
Array.isArray() | ✅ | Nhanh | Cao | ✅ CHUẨN |
Object.prototype.toString.call() | ✅ | Trung bình | Cao | ✅ Polyfill/Generic |
instanceof Array | ❌ | Nhanh | Thấp (cross-realm) | ⚠️ Chỉ same realm |
arr.constructor === Array | ❌ | Nhanh | Thấp (có thể spoof) | ❌ Không dùng |
Ví dụ từ bài gốc (đã cập nhật)
<script>
const sports = ["tennis", "football", "cricket"];
// Cách khuyến nghị
if (Array.isArray(sports)) {
alert("Là Array!");
} else {
alert("Không phải Array");
}
// Cách cũ (instanceof) - vẫn đúng trong same realm
if (sports instanceof Array) {
console.log("instanceof: Array");
}
</script>
Kiểm tra Array-like (Đối tượng giống mảng)
// Arguments, NodeList, HTMLCollection, {length: 2, 0: 'a', 1: 'b'}
function isArrayLike(obj) {
return obj != null &&
typeof obj.length === "number" &&
obj.length >= 0 &&
obj.length % 1 === 0 &&
obj.length <= Number.MAX_SAFE_INTEGER;
}
// Chuyển Array-like thành Array thật
const arr = Array.from(arrayLike); // ES6
const arr2 = [...arrayLike]; // ES6 (iterable)
const arr3 = Array.prototype.slice.call(arrayLike); // Cũ
TypeScript
// Type guard
function isStringArray(arr: unknown): arr is string[] {
return Array.isArray(arr) && arr.every(item => typeof item === "string");
}
const data: unknown = ["a", "b"];
if (isStringArray(data)) {
data.forEach(s => console.log(s.toUpperCase())); // type narrowed
}
Tóm tắt
- Luôn dùng
Array.isArray()– chuẩn ES5, cross-realm, nhanh, tin cậy. - Tránh
instanceof Arraytrong môi trường multi-frame (iframe, micro-frontend). - Dùng
Object.prototype.toString.call()cho generic type check. - Phân biệt Array thật vs Array-like (arguments, NodeList...).