在做一些数组相关的操作时,我们经常会遇到判断一个变量是否为数组的问题。下面简单记录几种常见的判断数组的方法。
对象原型上的方法
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++来写,通过判断数据结构来确认是否为数组的。而且这是内置方法,性能上更有优势。