前言:
此时朋友们对“如何判断一个js对象是否是array”大概比较看重,姐妹们都需要知道一些“如何判断一个js对象是否是array”的相关资讯。那么小编在网摘上收集了一些关于“如何判断一个js对象是否是array””的相关内容,希望看官们能喜欢,咱们快快来了解一下吧!今天分享一个平时经常用到但是不太注意的一个问题,那就是在js中如何判断一个东西是不是数组。
这个问题听起来好像挺简单的,但是能够很好的回答出来也是不简单的,我们一起来看一下。
以前常用的一种方法是使用Object.prototype.toString.call(目标对象)来通过返回结果判断是不是数组,我们看如下代码:
const arr = [1, 2, 3, 4, 5]const obj = { a: 1, b: 2 }console.log(Object.prototype.toString.call(arr)) // [object Array]console.log(Object.prototype.toString.call(obj)) // [object Object]
可以看到数组和对象返回结果通过第二个字符串就可以区分出来。
然后这种方法只适用于以前,这个以前指的是ES6引入一种新的原始数据类型Symbol以前,因为它有一个属性Symbol.toStringTag可以对Object.prototype.toString方法返回的字符串进行修改,这里引用阮一峰大神在第三版ES6标注入门中的解释:
对象的Symbol.toStringTag属性,用来设定一个字符串(设为其他类型的值无效,但不报错)。在目标对象上面调用Object.prototype.toString()方法时,如果Symbol.toStringTag属性存在,该属性设定的字符串会出现在toString()方法返回的字符串之中,表示对象的类型。也就是说,这个属性可以用来定制[object Object]或[object Array]中object后面的那个大写字符串。
意思就是我们可以通过以下代码将对象类型的数据也修改成[object Array]返回结果:
const obj = { [Symbol.toStringTag]: 'Array', a: 1, b: 2}console.log(Object.prototype.toString.call(obj)) // [object Array]
所以以前这种很好用的方法现在也用不了了。
那么第二种方法就是通过instanceof属性来判断,它是判断一个对象的原型链上有没有array的原型,我们也通过代码来看一下:
const arr = [1, 2, 3, 4, 5]const obj = { a: 1, b: 2}const obj1 = { [Symbol.toStringTag]: 'Array', a: 3, b: 4}console.log(arr instanceof Array) // trueconsole.log(obj instanceof Array) // falseconsole.log(obj1 instanceof Array) // false
可以看到对于普通数组,对象和Symbol.toStringTag修改的对象都能判断出来,但是它也有一些特殊情况:
const obj = { a: 1, b: 2}Object.setPrototypeOf(obj, Array.prototype)console.log(obj instanceof Array) // true
第一种特殊情况就是通过Object.setPrototypeOf方法修改原型的话就会判断错误。
第二种特殊情况就是如果在有iframe标签的页面中,因为iframe内部会有一套独立的window和documents,就会造成不同环境下虽然都是同一个Array构造函数,但是值不一样,所以就会造成判断错误。
最后一种方法就是通过Array构造函数上的isArray静态方法来判断,这个方法的描述mdn上是这样说明的:
Array.isArray() 检查传递的值是否为 Array。它不检查值的原型链,也不依赖于它所附加的 Array 构造函数。对于使用数组字面量语法或 Array 构造函数创建的任何值,它都会返回 true。这使得它可以安全地使用跨领域(cross-realm)对象,其中 Array 构造函数的标识是不同的,因此会导致 instanceof Array 失败。
经过测试,以上遇到的特殊情况也都能够准确的判断出来,大家可以自行测试一下。
标签: #如何判断一个js对象是否是array