【JS篇】JavaScript 中判断数组的 5 种常用方式详解

341 阅读3分钟

在 JavaScript 开发中,判断一个变量是否是数组类型是一个常见需求。由于 JavaScript 是一门动态类型语言,且数组本质上是对象(typeof [] === 'object'),因此不能直接使用 typeof 判断。

本文将系统讲解以下 5 种判断数组的方式

  1. Object.prototype.toString.call()
  2. 原型链判断(__proto__
  3. Array.isArray()
  4. instanceof Array
  5. Array.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() 方法作为兼容性兜底;