原生js如何判断是一个数组?

文章探讨了JavaScript中几种判断值是否为数组的方法,包括Object.prototype.toString.call(),instanceof,constructor,以及Array.isArray,并指出它们的优缺点和可能的误判情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Object.prototype.toString.call()

const isArray = (arr)=>{
    return Object.prototype.toString.call(arr) === "[object Array]"
}
const arr = [1,2,3,4];
const obj = {}
console.log(isArray(arr))    // true
console.log(isArray(obj))    // false

这样看起来没有问题,但是看一下下面的代码

const obj1 = {
    [Symbol.toStringTag]: "Array"
}
console.log(isArray(obj1))  // true 

因此,从上面的例子我们可以看出,对于大多数情况下,使用Object.prototype.toString.call()判断一个值是否为数组是有效的。但是,它可能存在一些问题和限制。

  • 误判其他类似数组的对象: Object.prototype.toString.call() 是根据对象的内部属性来判断类型。如果对象具有Symbol.toStringTag属性且内部值为Array,则无法正确判断对象是否为数组

instanceof

const isArray = (arr)=>{
    return arr instanceof Array
}
const arr = [1,2,3,4]
const obj = {}
const obj1 = {
    [Symbol.toStringTag]: "Array"
}
console.log(isArray(arr))   // true
console.log(isArray(obj))   // false
console.log(isArray(obj1))  // false

这种还会对继承类,也能准确判断出

class A extends Array {}
const arr1 = new A()
console.log(isArray(arr1))   // true

这样看起来似乎也没有什么题,但是看一下下面的代码

const obj2 = {};
Object.setPrototypeOf(obj, Array.prototype);
console.log(isArray(obj)); // true

因此,虽然instanceof在某些情况下可以用于判断值是否为真正的数组,但它也有局限性和误判的问题。

  • 原型链的问题:instanceof操作符会检查对象的原型链。因此,如果一个对象的原型链上的任何一个对象是Array.prototype,它也会被判断为数组

constructor

const isArray = (arr) => {
  return arr.constructor === Array;
};
const arr = [1, 2, 3, 4];
const obj = {
  [Symbol.toStringTag]: "Array",
};
const obj1 = {};
console.log(isArray(arr)); // true
console.log(isArray(obj)); // false
console.log(isArray(obj1)); // false

这样看起来似乎也没有什么问题,但是看一下下面的代码

class A extends Array {}
const arr1 = new A();
const arr2 = [];
arr2.constructor = Object;
const obj2 = {};
Object.setPrototypeOf(obj2, Array.prototype);
console.log(isArray(arr1)); // false
console.log(isArray(arr2)); // false
console.log(isArray(obj2)); // true
function CustomObject() {}
CustomObject.prototype = Object.create(Array.prototype);
const obj3 = new CustomObject();
console.log(isArray(obj3)); // true

从上面的例子可以看出,constructor在某些情况下可以用于判断值是否为真正的数组,但它也有局限性和误判的问题。

  • 对象的constructor属性可以被修改:constructor属性是一个指向创建对象的构造函数的引用。然而,它可以被修改,因此不能保证constructor属性的准确性
  • 对象原型链上的constructor属性可以被修改: 继承自数组原型链上的对象也会具有constructor属性,这可能导致误判

Array.isArray

const isArray = (arr)=>{
    return Array.isArray(arr)
}
const arr = [1,2,3,4];
class A extends Array {}
const arr1 = new A()
const obj = {}
Object.setPrototypeOf(obj,Array.prototype)
const obj2 = {
    [Symbol.toStringTag]: "Array"
}
console.log(isArray(arr))   // true
console.log(isArray(arr1))  // true
console.log(isArray(obj))   // false
console.log(isArray(obj2))  // false

Array.isArray()是一个用于判断一个值是否为数组的内置方法,它通常是判断一个值是否为数组的首选方法

参考文档

本文只介绍js判断是否为数组的原生方法以及存在的问题,关于兼容性问题没有展开说明,有兴趣的可以查看上面的参考文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值