面试题:如何判断 JavaScript 变量是数组?

在 JavaScript 中,由于数组本质上是对象,使用 typeof 无法准确判断数组类型(typeof [] 返回 "object")。因此,需要使用更可靠的方法来判断一个变量是否为数组。

以下是几种常用且推荐的方法,按优先级排序:


✅ 方法 1:Array.isArray()(推荐)

ES5 引入的 Array.isArray()最直接、最可靠的判断方法。

Array.isArray([])           // true
Array.isArray([1, 2, 3])    // true
Array.isArray(new Array())  // true

Array.isArray({})           // false
Array.isArray("array")      // false
Array.isArray(null)         // false
Array.isArray(undefined)    // false

优点

  • 语义清晰,专为判断数组设计。
  • 性能高。
  • 不受原型链或跨上下文环境(如 iframe)影响。

兼容性:现代浏览器和 Node.js 都支持。对于旧环境,可使用 polyfill。


✅ 方法 2:Object.prototype.toString.call()

利用 toString() 的内部行为,可以准确获取对象的“内部 [[Class]]”标签。

Object.prototype.toString.call([])        // "[object Array]"
Object.prototype.toString.call({})        // "[object Object]"
Object.prototype.toString.call(new Date()) // "[object Date]"

// 判断数组
function isArray(value) {
  return Object.prototype.toString.call(value) === '[object Array]';
}

isArray([1, 2]); // true

优点

  • 非常可靠,不受对象原型修改的影响。
  • 可用于判断其他内置对象类型(如 Date, RegExp)。

缺点

  • 代码稍长,不够直观。

⚠️ 方法 3:instanceof Array

[] instanceof Array         // true
[1, 2] instanceof Array     // true

问题

  • 跨 iframe 或跨窗口环境中会失效,因为不同全局环境中的 Array 构造函数不同。
  // 假设 arr 来自另一个 iframe
  const arr = window.frames[0].Array(1, 2);
  arr instanceof Array; // false!
  • 如果 Array 构造函数被修改,也可能出错。

结论不推荐在可能跨上下文的场景中使用。


❌ 不推荐的方法

1. typeof(完全无效)

typeof [] === "object" // true,但无法区分对象和数组

2. 检查 length 属性或数组方法

// 错误!对象也可以有 length 属性
const fakeArray = { length: 0 };
"length" in value && typeof value.length === "number" // 不能保证是数组

// 错误!方法可能被模拟
value.push && typeof value.push === "function" // 不可靠

3. constructor 属性

[].constructor === Array // true
// 但 constructor 可能被修改或不存在
const obj = Object.create(null);
obj.constructor = Array;
// obj 不是数组,但检查会通过

总结

方法是否推荐说明
Array.isArray(value)强烈推荐最标准、最安全的方法
Object.prototype.toString.call(value) === '[object Array]'✅ 推荐可靠,适用于需要兼容旧环境或判断多种类型
value instanceof Array⚠️ 谨慎使用在单全局环境且 Array 未被修改时可用,但有跨上下文问题
typeof, length, constructor❌ 不推荐不可靠或易被欺骗

最佳实践

  • 优先使用 Array.isArray()
  • 在需要支持非常旧的 JavaScript 环境时,使用 Object.prototype.toString.call() 作为 fallback。
  • 避免使用 instanceof Array,除非你完全控制运行环境。
THE END
喜欢就支持一下吧
点赞5 分享