在JavaScript中对于其8种数据类型js数据类型,没有直接且全面的检查数据类型的内置方法,目前知道的typeof和instanceof都不能完美解决问题。
本篇将介绍使用Object.prototype.toString如何完美解决此问题。首先我们来看看typeof 和 instanceof的缺点。
typeof操作符
typeof操作符可能是首先想到的。 它适用于number, string, undefined, boolean, symbol, function,但在使用typeof时有一些陷阱需要注意:
1、typeof null === 'object' 是一个已知的错误。 null不应该是object类型。
2、它除了function,无法区分普通对象和其他内置对象,如下示例。
typeof []; // 'object'
typeof {}; // 'object'
typeof new Date(); // 'object'
typeof /foo/; // 'object'
instanceof操作符
instanceof操作符通过检查对象的构造函数,来确定它是什么类型的,如下示例。
let Car = function () {};
let benz = new Car();
benz instanceof Car; // true
因此,instaceof虽然可以正确地确定对象的类型,但不能确定基本类型,如下示例。
[] instanceof Array // ✅ true
(() => {}) instanceof Function; // ✅ true
new Map() instanceof Map; // ✅ true
1 instanceof Number; // ❌ false
'foo' instanceof String; // ❌ false
另外,由于instanceof是通过检查对象的构造函数判断类型的,如果你在运行时修改了对象的原型,instanceof检查的结果可能会改变:
const array = [];
array instanceof Array; // ✅ true
Object.setPrototypeOf(array, null);
array instanceof Array; // ❌ false
正如您所看到的,typeof和instanceof都不是完美的,大多数时候人们必须同时结合这两种方法来进行类型检查。
Object.prototype.toString方法
事实证明,在JavaScript中还有第三种更好的检查数据类型的方法——Object.prototype.toString。
它是Object.prototype上的一个方法js数据类型,结果返回一个用于描述对象的字符串值,如下示例:
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call(1); // "[object Number]"
Object.prototype.toString.call('1'); // "[object String]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call(new String('string')); // "[object String]"
Object.prototype.toString.call(function () {}); // "[object Function]"
Object.prototype.toString.call(null); //"[object Null]"
Object.prototype.toString.call(undefined); //"[object Undefined]"
Object.prototype.toString.call(/123/g); //"[object RegExp]"
Object.prototype.toString.call(new Date()); //"[object Date]"
Object.prototype.toString.call([]); //"[object Array]"
Object.prototype.toString.call(document); //"[object HTMLDocument]"
Object.prototype.toString.call(window); //"[object Window]
可以使用regexp对其返回的字符串进行一些处理,封装一个通用的方法,适用于所有类型:
function getType(obj) {
const lowerCaseTheFirstLetter = (str) => str[0].toLowerCase() + str.slice(1);
// 如果是基本数据类型,直接使用typeOf操作符
const type = typeof obj;
if (type !== 'object') {
return type;
}
// 对对象类型使用 Object.prototype.toString 方法
return lowerCaseTheFirstLetter(
Object.prototype.toString.call(obj).replace(/^[object (S+)]$/, '$1')
);
}
getType([]); // "array"
getType('123'); // "string"
getType(null); // "null"
getType(undefined); // "undefined"
getType(); // "undefined"
getType(function () {}); // "function"
getType(/123/g); // "regExp"
getType(new Date()); // "date"
getType(new Map()); // "map"
getType(new Set()); // "set"
通过 Object.prototype.toString 就能够适用于所有数据类型的检查。这也是大部分框架、库中常用的方法。
限时特惠:本站每日持续更新海量设计资源,一年会员只需29.9元,全站资源免费下载
站长微信:ziyuanshu688