js判断数据类型
前言
js判断数据类型的方式有很多,并不存在说 哪个是最好的,看你的使用场景
typeof
只能判断基本数据类型 返回数据类型(字符串),对于引用类型 都会返回 object
const a = 1; // number
const b = 'hello'; // string
const c = {}; // object
const d = new Date(); // object
const e = []; // object
// 使用方式
console.log(typeof a)
console.log(typeof(e));
不过有几种特殊情况:null 也会返回 object、undefind返回字符串 undifend
instanceof
只能判断引用类型,返回是否是这个类型(布尔值),既检测一个对象是否是某个构造函数的实例
function Teacher() {};
// 使用方式
console.log('hello' instanceof(String)); // false
console.log(new Teacher() instanceof(Teacher)); // true
console.log(new Array() instanceof Array); // true
不过也存在特殊情况:它使根据是否存在于原型链来做依据的,于是便有下边的问题:不能精确判断Object类的具体数据类型
const arr = new Array();
console.log(arr instanceof Array); // true
console.log("abc" instanceof Object); // true
// 因为 Object 所有类型的超类,自然任何对象的原型链自然也会存在它
Object.prototype.toString.call
通过这种方式 可以更友好精准的获取类型,避免了上述两种方式的弊端
const a = 1;
const b = 'hello';
const c = {};
const d = new Date();
const e = [];
console.log(Object.prototype.toString.call(a)); // [object Number]
console.log(Object.prototype.toString.call(new Number(2))); // [object Number]
console.log(Object.prototype.toString.call(c)); // [object Object]
console.log(Object.prototype.toString.call(undefined)); // [object Undefined]
console.log(Object.prototype.toString.call(null)); // [object Null]
原理
Object.prototype.toString 是 Object 原型对象上的一个方法,用于返回一个表示对象类型的字符串,返回值格式为 [object Type],其中 Type 是对象的类型,代码大致如下
Object.prototype.toString = function () {
// 1. 获取 this 的 [[Class]] 内部属性
const type = this.[[Class]]; // [[Class]] 是 JavaScript 内部的类型标记
// 2. 返回格式化的字符串
return `[object ${type}]`;
};
虽然说有对象都继承自它,但是所有类(构造函数)都重写此方法,所以 你不能像直接调用 new Array[].toString()
。但是我们通过 call 或者 applay 借调 它,Object.prototype.toString.call(xx) ,此时 Object.prototype.toString 内的 this 就是 xx 了,这是 call 或者 applay 知识,更多可以自己了解!
优化
// Object.prototype.toString,让其返回值更人性化
const oldObjToString = Object.prototype.toString;
Object.prototype.toString = function () {
const res = oldObjToString.call(this);
return res.match(/\[object (\w+)\]/)[1];
};
console.log(Object.prototype.toString.call(1)); // Number