判断是否是数组
刀刀
4/7/2025
0 字
0 分钟
判断是否是数组有以下几种方法:
- Object.prototype.toString
- instanceof
- isArray
Object.prototype.toString
下面来看一段代码:
js
let arr = [1, 2, 3]
let obj = {}
console.log(Object.prototype.toString.call(arr)) // [object Array]
console.log(Object.prototype.toString.call(obj)) // [object Object]
因此可以通过第二个单词是否是 Array
来判断该变量是否是数组。在过去可以写出以下代码来判断:
js
function isArray(arr) {
return Object.prototype.toString.call(arr) === '[object Array]'
}
在以前这个方法是可以使用的,但是现在不可以了。在之前变量无法更改这个字符串,但是现在可以可以了,通过 toStringTag
来修改。代码如下:
js
let obj = {
[Symbol.toStringTag]: 'Array'
}
isArray(obj) // true
因此这个方法现在无法百分百保证正确了。
instanceof
instanceof 能判断一个变量的原型链条上有没有 array
的原型,代码如下:
js
function isArray(arr) {
return arr instanceof Array
}
let obj = {
[Symbol.toStringTag]: 'Array'
}
isArray(obj) // false
class A extends Array {}
const a = new A()
isArray(a) // true
该方法也能正常运作,且不会受 toStringTag
的影响,继承也能够正常识别。
但是它还是有两个问题:
- 使用
setPrototypeOf
修改原型为数组原型会判断为true
iframe
是独立的,它有自己的window
环境,如果使用iframe
内的数组环境生成的变量,原型判断为false
代码如下:
js
// setPrototypeOf
let obj = {}
Object.setPrototypeOf(obj, Array.prototype)
isArray(obj) // true
// iframe
let Array1 = window.Array
let iframe = document.querySelector('iframe')
let Array2 = iframe.contentWindow.Array
console.log(Array1 == Array2) // false
let arr = new Array2()
console.log(arr instanceof Array) // false。Array是当前环境的Array,不是iframe的Array,所以是false
isArray
数组是一个特殊的对象,底层源码会有一个特殊的存储结构,在浏览器控制台输入 Array
可以看到。
所以需要一个方法判断该对象是否经过这些构造函数。isArray
方法判断的依据就是当前变量是否经过 native code
。下面来看一下代码:
js
let Array2 = iframe.contentWindow.Array
let arr = new Array2()
console.log(Array.isArray(arr)) // true
let obj = {}
Object.setPrototypeOf(obj, Array.prototype)
console.log(Array.isArray(obj)) // true