最推荐 Array.isArray():ES5 标准方法,可靠跨环境;次选 Object.prototype.toString.call():底层安全,可扩展;instanceof 和 constructor 易受跨 iframe 或原型污染影响,不建议生产使用。

JavaScript 中检测数组和普通对象,关键不是“看起来像不像”,而是看它在语言规范中属于哪种构造类型。数组是 Array 构造函数的实例,有专属行为(如 length、索引赋值、内置方法);普通对象是 Object 实例或字面量,用于键值对存储。两者都属于引用类型,typeof 都返回 "object",所以必须用更精确的方法区分。
最推荐:Array.isArray()
这是 ES5 引入的官方标准方法,专为判断数组设计,可靠、简洁、跨环境安全:
- 返回布尔值,语义清晰:
Array.isArray([])→true,Array.isArray({})→false - 能正确处理 iframe 或不同上下文中的数组(
instanceof在这类场景会失效) - 现代浏览器和 Node.js 全面支持,无兼容性顾虑
较可靠:Object.prototype.toString.call()
利用每个对象内部的 [[Class]] 标签,通过统一接口获取类型标识符:
-
Object.prototype.toString.call([])返回"[object Array]" -
Object.prototype.toString.call({})返回"[object Object]" - 比
instanceof更底层,不受原型链污染或跨 frame 问题影响 - 可扩展用于检测
Date、RegExp、Map等其他内置类型
需谨慎:instanceof 和 constructor
这两者依赖原型链,容易在复杂环境中出错:
立即学习“Java免费学习笔记(深入)”;
-
[] instanceof Array通常为true,但若数组来自另一个 iframe,instanceof Array会返回false -
arr.constructor === Array同样受跨环境影响,且可能被手动修改(如arr.constructor = Object) - 不建议单独用于生产环境的类型断言,仅适合可控的单上下文调试
辅助参考:length 属性与数组特性
这不是类型检测方法,但可作为快速经验判断的补充线索:
- 数组一定有
length属性,且为非负整数;普通对象一般没有该属性(除非手动添加) - 数组支持数字索引赋值并自动更新
length,如arr[10] = 'x'会让arr.length变为11 - 但注意:类数组对象(如
arguments、DOM NodeList)也有length和数字索引,却不是数组 —— 所以不能单靠length下结论


















