如何在JavaScript中检查对象是否为数组:3种最佳方法

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

如何在JavaScript中检查对象是否为数组:完整指南

\n\n

您是否曾经有过这样的想法:“明明传了一个数组,但代码却报错了”?这种情况很常见。在JavaScript中,数组是对象,简单的typeof检查在这里行不通。今天我们将解析三种主要方法来检查对象是否为数组,并找出在实际项目中应该使用哪一种。

\n\n

为什么typeof不适用?

\n\n

在深入探讨之前,我们先来了解一下为什么新手经常在这里犯错。在JavaScript中,数组是对象的一种特殊情况。因此,对数组使用typeof运算符会返回"object",而不是"array"。您可以自己试试:

\n\n
const arr = [1, 2, 3];\nconsole.log(typeof arr); // "object" — 毫无用处
\n\n

此外,typeof null === "object"是语言中一个众所周知的bug,已经无法修复。因此,如果您正在检查来自用户或API的数据,不能依赖typeof。需要更可靠的方法。

\n\n

方法1:Array.isArray() — 现代标准

\n\n

从ES5(2009年)开始,JavaScript内置了Array.isArray()方法。这是检查对象是否为数组最正确、最简单的方法。

\n\n
const arr = [10, 20, 30];\nconst notArr = { length: 3, 0: 'a', 1: 'b', 2: 'c' };\n\nconsole.log(Array.isArray(arr));    // true\nconsole.log(Array.isArray(notArr)); // false\nconsole.log(Array.isArray('hello')); // false\nconsole.log(Array.isArray(null));    // false
\n\n

为什么这是最佳选择?因为Array.isArray()即使在多框架场景下也能正确工作:如果数组来自另一个iframe或框架,instanceof可能会失效,但Array.isArray()不会。它检查对象的内部类型[[Class]],而不是原型链。

\n\n

浏览器支持

\n

该方法支持所有现代浏览器,包括Internet Explorer 9+。如果您需要支持非常旧的浏览器(IE 8及以下),请使用polyfill或第三种方法。

\n\n

方法2:instanceof Array — 经典方法

\n\n

instanceof运算符检查对象的原型链中是否存在Array.prototype原型。听起来很复杂,但实际上是这样工作的:

\n\n
const arr = [1, 2, 3];\nconsole.log(arr instanceof Array); // true\n\nconst obj = { a: 1 };\nconsole.log(obj instanceof Array); // false\n\n// 但这里有个意外:\nconst iframeArr = new iframe.contentWindow.Array(1, 2, 3);\nconsole.log(iframeArr instanceof Array); // false! (如果数组来自另一个框架)
\n\n

问题就在这里:如果您的页面上有多个iframe,或者您在使用Web Workers,来自不同全局上下文的数组具有不同的原型。instanceof没有考虑到这一点,可能会对真正的数组返回false。因此,在现代开发中,最好避免使用instanceof来检查数组。

\n\n

方法3:Object.prototype.toString.call() — 万能方法

\n\n

这种方法在Array.isArray()出现之前被使用。如果您需要编写polyfill或在Array.isArray不可用的环境中工作,它仍然有效。

\n\n
function isArray(obj) {\n  return Object.prototype.toString.call(obj) === '[object Array]';\n}\n\nconsole.log(isArray([1, 2]));      // true\nconsole.log(isArray({ a: 1 }));    // false\nconsole.log(isArray('string'));    // false\nconsole.log(isArray(null));        // false
\n\n

这是如何工作的?Object.prototype对象的toString方法返回一个类似[object Type]的字符串。对于数组,它始终是[object Array]。这种方法绕过了iframe的问题,因为它检查内部类

博客

书籍推荐