获取一个对象的类型,对typeof扩展:
没有一个方法可以直接知道到一个对象的类型,因此结合toString()方法、constructor 对 typeof 进行一个扩展,可以获得所有对象的类型
运用的原理:
-
typeof null === ‘null’;
typeof undefined === ‘undefined’;
typeof 简单数据类型 === 本身的类型
typeof 函数=== 'function’
typeof 对象、数组 === ‘object’
缺点:对象类型和数组分不清 -
Object.prototype.toString.apply(1) === [object Number]
Object.prototype.toString.apply(’’) === [object String]
Object.prototype.toString.apply(null) === [object Null]
…等简单数据类型可以判断出来
Object.prototype.toString.apply(函数) === [object Function]
Object.prototype.toString.apply(数组) === [object Array]
…等内建对象也可以判断出来;例如:Date类型、Math类型…
缺点:但是自己定义的对象没有办法判断;例如:
构造函数:function Circle (a) { this.r = a; }
创建实例:const c = new Circle(5);
Object.prototype.toString.apply( c) === [object Object];
另:此处为什么用apply借用Object.prototype的toString方法,是因为可能有些对象中改写了toString方法,此处用Object.prototype的更加安全 -
instanceof方法
数组a instanceof Array ===>true;
数组a instanceof Object ===> true;
…
这句话可以翻译成数组a的原型链上有Array吗?数组a的原型链上有Object 吗?
这可以用来判断已知的类型 -
constructor
constructor可以看自己定义的对象的类型,即它的构造函数。
下面是根据上述的几个方法,总结的可以判断所有据类型的函数
function getType(a) {
if (a === null) { // null
return 'null';
}
if (typeof a !== 'object') {
return typeof a; // 简单数据类型、函数
}
const b = Object.prototype.toString.apply(a);
const c = b.substring(8,b.length-1);
if (c !== 'Object') {
return c; // 内建对象Array、Date...等
}
if (a.constructor === Object) {
return c; // Object的实例
}
if ('classname' in a.constructor.prototype && typeof a.constructor.prototype.classname === 'string') {
return a.constructor.prototype.classname; //自己定义的类
}
return '<unknown type>';
}