前言
大家工作中必定会经常会对类型做判断,从而实现一些逻辑处理,那咱们就话不多说,今天带领大家来搞一下这个类型检测
本文需要知识点
-
原型链
-
数据类型种类
检测数据类型
tyepof
instanceof
constructor
Object.prototype.toString.call()
typeof篇
我给大家分了一些类 可以稍微看下,----------大家看完就会发现 null 数组 正则都是 Object;
typeof 12; typeof NaN // number
typeof "" // string
typeof true // boolean
typeof undefined // undefined
typeof function () { }; // function
typeof null; typeof {}; typeof []; typeof /^$/ // Object Why???
这个经过大量的查询,发现 typeof会在计算机底层基于二进制来进行检测, 而且对象都是以 000 开头的, 所以检测出来也是 Object
instanceof 篇
很多经典面试题,就会问你 instanceof 和 typeof 区别 大家可以看到typeof arr 即是 数组 又是对象 why?
let arr = [];
arr instanceof Array // true
arr instanceof RegExp // false
arr instanceof Object // true
function fn() {
}
fn.prototype = Array.prototype;
let f = new fn;
console.log(f,f instanceof Array) // true
fn instanceof Array // true
fn instanceof Object // true
let num = 1;
num instanceof Number
铁铁,你可以打开他的原型链瞅一眼,你会发现 他是根据 只要出现在原型链上面,他就是true;
当你 取检测基本数据类型的时候,你就会发现他都是false,也就是不支持基本数据类型检测;
最重要的一点,可以自由修改原型
如何实现 instanceof
// 如果实现一个 instanceof 呢?
function instance_of(current, target) {
let targetPrototype = target.prototype;
let proto = Object.getPrototypeOf(current) // 兼容IE 取原型
while (true) {
if (proto === null) return false;
if (proto === targetPrototype) return true;
proto = Object.getPrototypeOf(proto);
}
}
constructor 篇
一些人可能对这个方法有些陌生,他的原型上面会有一个constructor的,会标志他是属于什么类型的, 在一般情况下(无外力介入)还是比较准的,给大家准备了些小例子
let arr = [];
let num = 1;
// Number.prototype.constructor = '哦豁豁哦豁豁';
// Numbrr.constructor === Number // false
brr.constructor === Number // true
arr.constructor === Array // true
arr.constructor === RegExp // false
arr.constructor === Object // false
Object.prototype.toString() 篇
这个标准的辨别类型的方法,但是有个缺点,麻烦,这老多字母
// 当定义个对象,然后调用原型上的 toString方法时,
// 因为此时 toString方法 指向调用它的
let obj = {
name: '彭于晏'
};
obj.toString() // "[object,Object]"
// 咱们猜一把: 既然Object.prototype.toString会返回object,通过call来改变this是他不指向Object,
//而是调用者的时候, 就会发现,没有一个重复的,哇哈哈哈,标准
如何实现一个toType方法呢?
结合他们的优缺点实现
function toType(obj) {
if (obj == null) { // 注意 不是绝对等于
return obj;
}
return typeof obj === "object" || typeof obj === 'function' ? Object.prototype.toString(obj) || "object" : typeof obj;
}
总结
-
typeof 适合检测基本数据类型 当然函数也行,对象差点意思
直接在计算机底层 基于数据类型的值(二进制)进行检测
typeof null;
why? 因为typeof 在底层检测的时候,对象都是以 000 开头的, null 也是 所以检测出来就是对象 -
instanceof 检测当前实例是否属于这个类 准确性不好
底层: 当前类只要出现在实例原型链上 都是 true
js对原型指向问题,支持度比较高,所以会导致instanceof 检测不准
而且不支持检测基本数据类型 -
constructor
无外力介入的情况下还是比较准的,而且基本类型也支持。(无外力介入:不人为去修改) -
Object.prototype.toString.call()
标准检测数据类型 Object.prototype.toString 返回当前实例所属;