小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
数组是我们日常开发离不开的,判断一个数据类型是否为数组也是一件十分常见的事情,那么如果让你判断一个数据是否为数组,此时的你能想到几种方式呢?各自又有什么用的优缺点呢?
接下来便一起看看吧
typeof
相信很多人在脑中快速搜索答案时,typeof应该是最容易想到的数据类型判断的方式
对于 Function、String、Number、Undefined 等几种类型的对象来说,typeof完全没有压力的可以胜任
typeof 1; // 'number'
typeof '1'; // 'string'
typeof undefined; // 'undefined'
typeof true; // 'boolean'
typeof Symbol(); // 'symbol'
typeof null; // 'object'
const fn = () => {};
typeof fn; // 'function'
但是在上述之外的数据类型检测时,typeof就显得力不从心了
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
可以发现使用typeof类型检测结果均为object,而数组恰恰在此之列
结论:typeof虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了 function 类型以外,其他的也无法判断
Instanceof
想必 instanceof 的方法大家也不会陌生,我们 new 一个对象,那么这个新对象就是它原型链继承上面的对象了,通过 instanceof 我们能判断这个对象是否是之前那个构造函数生成的对象,这样就基本可以判断出这个新对象的数据类型
判断引用数据类型
class Animal{}
const animal = new Animal();
console.log(animal instanceof Animal); // true
const newNum = new Number(12);
console.log(newNum instanceof Number); // true
const arr = [1, 2] // 等价于 new Array(1, 2)
console.log(arr instanceof Array); // true
判断基础数据类型
let num = 123;
console.log(num instanceof Number); // false
结论:instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
constructor
在JS中,每个对象都有一个constructor属性,它引用了初始化该对象的构造函数,一般情况下,除了 undefined 和 null,其它都能使用 constructor 判断类型
const arr = [];
console.log(arr.constructor === Array); // true
但是由于JS的灵活性,导致其在有些时候是不准确的,比如我们可以人为的修改constructor
const arr = [];
arr.constructor = Object;
console.log(arr.constructor === Array); // false
Object.prototype.toString
toString 是 Object 的原型方法,调用该方法,可以统一返回格式为 “[object 数据类型]” 的字符串
对于 Object 对象,直接调用 toString() 就能返回 [object Object];而对于其他对象,则需要通过 call 来调用,才能返回正确的类型信息
Object.prototype.toString({}) // "[object Object]"
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call('1') // "[object String]"
结论:点用toString方法判断数据类型,可以很稳定的得到期望的类型检测结果,适用于全部数据类型
Array.isArray
Array.isArray是ES标准提供的一个方法
Array.isArray([]) // true
Array.isArray(1) // false
结论:ES标准提供,弊端是存在兼容性问题