详细介绍5种方法检查JavaScript对象是否数组
作者:admin 时间:2022-5-31 20:17:3 浏览:“数组是类似列表的对象,其原型具有执行遍历和变异操作的方法。” — MDN 文档
如何在 JavaScript 中检查对象是否数组?本文将详细介绍 5 种方法,并比较它们的优缺点:
- 方法1) Array.isArray([])
- 方法2) Object.prototype.toString.call([])
- 方法3) [] instanceof 数组
- 方法4) [].constructor
- 方法 5) && 与 [].constructor
方法一:Array.isArray([])
ECMAScript 5 (ES5) 引入了 Array.isArray()
方法来检查数组,因为 typeof
无法将数组与其他对象区分开来,例如内置对象 Date
和 RegExp
。
使用 Array.isArray()
也有助于确保我们的对象不为空,因为由于长期存在的错误,null
具有“对象”类型。
下面是使用 Array.isArray([])
检查数组的示例:
方法二:Object.prototype.toString.call([])
冗长的 JavaScript 语句 Object.prototype.toString.call()
可以区分数组和其他类型的对象,因为它返回的字符串比 typeof
更详细地指定了对象类型。
因为此方法适用于任何对象,所以我称其为 JavaScript 中类型检查的最佳方法。这是一个例子:
虽然冗长,但此方法适用于任何原始类型和任何对象。它总是返回变量的构造函数的名称。
换句话说,Object.prototype.toString.call()
有点像 instanceof
的逆向,尽管它在 iframe 中运行良好。
上述 isArray()
函数的行为应该与内置的 Array.isArray()
函数相同。
这里要注意的一点是 typeof {}
返回“object
”(小写),但 Object.prototype.toString.call({}).slice(8,-1)
返回“Object
”(大写)对象 {}
和数组 []
的“Array
”(大写)。
与所有这些方法一样,如果尚未声明变量,此方法将不起作用。稍后我将讨论检查未声明的变量。
方法三:[] instanceof 数组
使用关键字 instanceof
可用于检查数组或任何类型的 JavaScript 对象。
“instanceof 运算符测试构造函数的原型属性是否出现在对象原型链的任何位置。” — MDN 文档
语法很简单,如下代码示例所示:
但请注意,iframe 可能会破坏这种行为,如 Mozilla 开发人员网络文档中 Array.isArray
中所述:
instanceof vs isArray
在检查 [an] Array 实例时,Array.isArray
优于instanceof
,因为它通过 iframe 工作。— MDN 文档
这意味着我们可能根本不想使用 instanceof
来检查数组,以防万一我们的 JavaScript 代码最终在 iframe 中运行。
方法四:[].constructor
这是一个类似于 instanceof
的方法——调用 JavaScript 对象的 .constructor
属性。
.constructor
属性将返回构造函数,对于数组,它是函数 Array()
(即 JavaScript 类 Array
)。
访问该函数的 .name
属性将给出字符串“Array”,该字符串可用于形成对数组是否存在的简单检查。
由于 .constructor
属性返回函数 Array()
(即 JavaScript 类 Array
),因此也可以直接将其与全局 Array
对象(即返回的函数 Array()
所引用的对象)进行比较。
换句话说,实际上不必使用 .name
属性:[].constructor===Array
等价于 [].constructor.name==="Array"
。
这是一个代码示例:
与 Object.prototype.toString.call()
类似,访问 .constructor
属性将适用于任何类型的 JavaScript 值,包括原语——尽管您不能访问 .constructor
以获取未定义或空值。
(请注意,instanceof
关键字适用于对象,但不适用于基元。当然,instanceof
在 iframe 中存在错误。)
正如我们在上面看到的,使用没有 null
检查的 .constructor
会导致 null 和 undefined 的 TypeError
— 与 Array.isArray()
相比的缺点,后者只会为这两个值返回 false。
并且,与到目前为止介绍的任何方法一样,如果想尝试访问未声明的变量,它们将引发 ReferenceError
。
一句警告:.constructor
是可变的
在继续之前,值得注意的是 .constructor
并不健壮,因为它是一个可以在以后覆盖的对象属性。
请记住,如果你出于任何原因通过原型覆盖您的构造函数,则 arr.constructor === Array
测试将返回 false
。Array.isArray(arr)
仍然返回 true
。
所以只要记住一个对象的 .constructor
属性是“可变的”——它可能已经在代码中的某个地方从它的原始值改变了。
方法 5:&& 和 [].constructor(空检查!)
这是一个简洁的单行代码,它将在检查数组的同时检查非空值:[] && [].constructor === Array
。
null
和 undefined
都是false
,这意味着它们在条件语句中评估为false
,但所有对象都是true
,包括空数组。检查 [] && [].constructor === Array
将为 null
或未定义的值返回 false
,而单独的 .constructor
会引发错误。
包含逻辑 AND (&&)
运算符的优点是可以避免由于 null
和 undefined
没有属性而发生的 TypeError
。这是有效的,因为 &&
是一个“短路运算符”。通过使用逻辑 AND (&&)
,我们在尝试访问 .constructor
属性之前检查该值是否为true
。这是一个代码示例:
为了提高代码的可读性,你可以考虑使用松散相等(==
)来显式地检查空值:[] != null && [].constructor
。使用 !=
(松散相等运算符)意味着 null
和 undefined
彼此相等。
更明确的检查将使用严格相等:[] !== null && [] !== undefined && [].constructor === Array
。许多 JavaScript 程序员宁愿从不使用松散相等,因为 ==
的规则令人困惑。
使用 && 和 .constructor
对 null
和 undefined
的工作方式与 Array.isArray()
的效果相同:它返回 false
,正如你所希望的那样。
但是,未声明的变量在尝试访问 .constructor
属性时仍会引发 ReferenceError
。你可以在数组检查之前使用 typeof
检查该值是否“undefined
”以解决该问题。
如果数组变量实际上是未声明的怎么办?
你可能不确定是否实际上已经声明了可能是数组的变量。让我简单谈谈检查未声明的数组。
提醒一下,访问尚未声明的变量将引发 ReferenceError
,而已声明但未分配特定值的变量将具有 undefined
值。
值得庆幸的是,typeof
关键字将为尚未声明的变量返回“undefined
”,与未定义的值相同,但不会抛出 ReferenceError
,因为该变量还没有被声明。
这意味着我们可以将 Array.isArray()
包装在 typeof
调用中,以使其对未声明的变量具有鲁棒性。这是一个例子:
或者,我们可以使用 try...catch
块来捕获潜在的 ReferenceError
,但 typeof
对未声明的变量同样有效。
如何在 JavaScript 中检查空数组?
相反,如果我们想检查一个数组是否为空,我们可以检查它的 .length
属性——一个空数组的 .length
为 0。
同样,我们需要确保我们正在使用一个已声明的变量,该变量已经分配了一个绝对是数组的值。
但是,假设我们从 Array.isArray([])
得到 true
,那么 [].length > 0
将确认我们的数组不为空。这是一个代码片段:
同样,我们正在利用 &&
作为短路运算符。因为它在错误陈述上“短路”,所以我们永远不会达到上面示例中的 .length
调用。这正是我们想要的,因为 .length
不适用于大多数原语,如数字或其他类型的对象。
总结
本文详细介绍了5 种不同的检查 JavaScript 数组的方法。我在编码时通常使用 Array.isArray()
,有几个原因:
- Array.isArray() 快速且得到广泛支持。
- Array.isArray() 是显式的,使您的代码更具可读性。
- Array.isArray() 为 null 和未定义返回 false。
有时,在我担心未声明变量的罕见情况下,我会将数组检查包含在 if(typeof !== "undefined")
语句中。
参考文章
相关文章
- 站长推荐