在 JavaScript 开发中,判断一个变量是否是数组类型是一个常见需求。由于 JavaScript 是一门动态类型语言,且数组本质上是对象(typeof [] === 'object'),因此不能直接使用 typeof 判断。
本文将系统讲解以下 5 种判断数组的方式:
Object.prototype.toString.call()- 原型链判断(
__proto__) Array.isArray()instanceof ArrayArray.prototype.isPrototypeOf()
并分析它们的适用场景、优缺点和注意事项。
✅ 一、使用 Object.prototype.toString.call() 判断
🔍 示例代码:
function isArray(obj) {
return Object.prototype.toString.call(obj).slice(8, -1) === 'Array';
}
console.log(isArray([])); // true
console.log(isArray({})); // false
📌 原理说明:
- 所有对象都继承自
Object; toString()返回的是[object 类型]格式;Array的返回值为[object Array];- 使用
.slice(8, -1)提取出“Array”部分;
✅ 优点:
- 最通用、最安全的方法;
- 可以跨框架/窗口使用(如 iframe);
- 不受原型链修改影响;
❌ 缺点:
- 写法略复杂;
- 需要手动提取字符串;
✅ 二、通过原型链判断(__proto__)
🔍 示例代码:
function isArray(obj) {
return obj.__proto__ === Array.prototype;
}
console.log(isArray([])); // true
console.log(isArray({})); // false
📌 原理说明:
- 每个数组实例的
__proto__都指向Array.prototype; - 直接比较即可判断是否是数组;
✅ 优点:
- 简单直观;
❌ 缺点:
__proto__已被废弃(虽然现代浏览器仍支持);- 在某些环境中可能不可用(如严格模式或 ES6 模块);
- 如果对象的原型被修改过,可能会出错;
✅ 三、使用 Array.isArray() 方法(推荐)
🔍 示例代码:
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
📌 原理说明:
Array.isArray()是 ES5 新增的标准方法;- 专门用于判断是否是数组类型;
✅ 优点:
- 最简洁、最标准的方式;
- 性能好、可读性强;
- 被广泛支持(包括 IE9+);
❌ 缺点:
- 无法兼容非常旧的浏览器(如 IE8 及更早版本);
📌 推荐指数:⭐⭐⭐⭐⭐(首选方式)
✅ 四、使用 instanceof Array
🔍 示例代码:
console.log([] instanceof Array); // true
console.log({} instanceof Array); // false
📌 原理说明:
instanceof检查构造函数的原型是否存在于对象的原型链上;- 数组实例的原型链包含
Array.prototype;
✅ 优点:
- 语法简单;
- 易于理解;
❌ 缺点:
- 在跨框架或跨窗口时(如 iframe)可能失效;
- 对象来自不同执行上下文时判断会失败;
✅ 五、使用 Array.prototype.isPrototypeOf()
🔍 示例代码:
console.log(Array.prototype.isPrototypeOf([])); // true
console.log(Array.prototype.isPrototypeOf({})); // false
📌 原理说明:
isPrototypeOf()方法用于检查某个对象是否存在于另一个对象的原型链中;- 数组实例的原型链中包含
Array.prototype;
✅ 优点:
- 可用于检测对象是否具有某个原型;
❌ 缺点:
- 写法不如
Array.isArray()简洁; - 可读性较差;
- 同样不适用于跨框架环境;
📊 五种方法对比总结表
| 方法 | 是否标准 | 是否兼容 iframe | 是否推荐 | 备注 |
|---|---|---|---|---|
Object.prototype.toString.call() | ✅ | ✅ | ⭐⭐⭐⭐⭐ | 通用、可靠 |
__proto__ | ❌(已废弃) | ✅ | ⭐⭐ | 不推荐 |
Array.isArray() | ✅ | ✅ | ⭐⭐⭐⭐⭐ | 推荐首选 |
instanceof Array | ✅ | ❌ | ⭐⭐⭐ | 注意跨域问题 |
Array.prototype.isPrototypeOf() | ✅ | ✅ | ⭐⭐⭐ | 了解即可 |
✅ 实际开发建议
| 场景 | 推荐方法 |
|---|---|
| 现代浏览器项目 | Array.isArray() ✅ |
| 兼容旧版浏览器(如 IE9) | Object.prototype.toString.call() ✅ |
| 判断自定义类的实例 | instanceof 更合适 |
| 跨 iframe 或 window 通信 | 使用 toString() 方法 ✅ |
| 简洁易读 | Array.isArray() ✅ |
💡 进阶建议
- 学习 TypeScript 中如何使用类型守卫(Type Guard)判断数组;
- 了解
Symbol.hasInstance方法,可以自定义instanceof行为; - 在 Vue / React 中结合 PropTypes 或 TypeScript 类型系统提升类型安全性;
- 使用 Lodash 的
_.isArray()方法作为兼容性兜底;