javascript中精确区分object、array和function应优先用array.isarray()判数组,typeof判函数,object.prototype.tostring.call()统一识别三者;避免instanceof、constructor及单纯typeof等误判方法。

JavaScript 中,Object、Array 和 Function 都属于引用类型,但它们的语义、行为和构造方式完全不同。用错判断方法容易误判——比如 typeof [] 和 typeof {} 都返回 "object",而 typeof function(){} 虽然返回 "function",但某些环境(如旧版 Safari)曾将其归为 "object"。所以“精确区分”必须避开陷阱,选对方法。
用 Array.isArray() 判断数组最可靠
这是 ES5 标准方法,跨 iframe、跨窗口、多全局环境都稳定有效:
-
Array.isArray([])→ true -
Array.isArray({})→ false -
Array.isArray(function(){})→ false
不推荐用 instanceof Array 或 constructor === Array:前者在 iframe 场景下失效;后者可被手动篡改(如 arr.constructor = Object),导致误判。
用 typeof + 严格补充判断 Function
typeof 对函数返回 "function",目前主流引擎已统一支持,是首选:
-
typeof function(){} === "function"→ true -
typeof class A{} === "function"→ true(类本质也是函数) -
typeof {} === "function"→ false
注意:不能单靠 typeof 区分 Object 和 Array(两者都是 "object"),所以它只适合专用于识别函数——且要配合其他方法排除干扰。
用 Object.prototype.toString.call() 统一识别三者
这是最底层、最通用的方案,能精准返回内部 [[Class]] 标签:
-
Object.prototype.toString.call([])→"[object Array]" -
Object.prototype.toString.call({})→"[object Object]" -
Object.prototype.toString.call(function(){})→"[object Function]"
这个方法不依赖构造函数,不受原型链污染或跨环境影响,适用于需要同时判断多种内置类型的场景(如 Date、RegExp、Map 等)。只需提取中括号内的单词即可标准化比对。
避免常见误判组合
有些看似直观的方式实际不可靠:
-
typeof单独用于对象/数组 → 两者都返回"object",无法区分 -
obj instanceof Object→ 几乎所有引用类型都为 true(包括 Array、Function),失去区分意义 - 检查
length属性 → 类数组对象(如arguments、NodeList)也有 length,但不是 Array - 检查
typeof obj === "object" && !Array.isArray(obj)→ 可识别普通对象,但会把null也当作 object(typeof null === "object"是历史 bug)
真正安全的做法是:先用 Array.isArray() 排除数组;再用 typeof === "function" 捕获函数;其余满足 typeof === "object" 且非 null 的,才归为普通 Object。











