Array Types

How to determine whether a variable is an array ?

Posted by My on June 30, 2022

在做一些数组相关的操作时,我们经常会遇到判断一个变量是否为数组的问题。下面简单记录几种常见的判断数组的方法。

对象原型上的方法

Object.prototype.toString.call() 方法可以用来判断变量的类型。

  • 判断数组

    1
    
    Object.prototype.toString.call([]); // [object Array]
    
  • 判断对象

    1
    
    Object.prototype.toString.call({}); // [object Object]
    
  • 判断函数

    1
    
    Object.prototype.toString.call(function () {}); // [object Function]
    
  • 判断 null

    1
    
    Object.prototype.toString.call(null); // [object Null]
    
  • 判断 undefined

    1
    
    Object.prototype.toString.call(undefined); // [object Undefined]
    
  • 判断字符串

    1
    
    Object.prototype.toString.call("hello"); // [object String]
    

这个在以前是非常有用的,或者说就得用这种方式来判断变量类型。但是 ES6 引用了一个符号 Symbol.toStringTag ,这个可以「影响」到变量的类型。

1
2
3
4
5
6
const obj = {
  a: 123,
  [Symbol.toStringTag]: "hello",
};
const type = Object.prototype.toString.call(obj);
console.log(type); // [object hello]

通过例子可以发现,Symbol.toStringTag 可以指定类型,所以在一定程度上来说,会影响到判断结果。但是哪个人会这么扯淡去改这个呢? 所以说,一般公司的业务开发,用这个方法还是能很准确地判断变量类型的。

instanceof 运算符

这是通过原型链的方式来判断类型的,我们都知道「对象」是通过 new 出来的,而且对象的 __proto__ 指向构造函数的原型。 比如 arr 是通过 new Array() 出来的,那 arr 的 __proto__ 指向 Array.prototype。

1
2
const arr = [];
console.log(arr instanceof Array); // true

当然,这个也有问题,我们可以手动修改原型。

1
2
3
const obj = {};
Object.setPrototypeOf(obj, Array.prototype);
console.log(obj instanceof Array); // true

一个 obj ,我们修改了原型,变成了数组,虽然我们的目的和结果都对上了,但是从理解的角度来说,结果并不正确。 这个 obj 并不是我们所认为的数组的结构,所以这么处理后,我们可以认为结果是不正确的。

当然了,很少有人会这么处理,因此简单的判断还是可以使用这种方式的。

Array.isArray() 方法

这是 ES6 引入的方法,可以用来判断变量是否为数组。

1
2
const arr = [];
console.log(Array.isArray(arr)); // true

这个是最准确判断数组的方法,不会受到原型链的影响。是使用C++来写,通过判断数据结构来确认是否为数组的。而且这是内置方法,性能上更有优势。