全网最全JS数据类型检测方法及底层机制

四种检测数据类型的方法

1.typeof
2.instanceof
3.constructor
4.Object.prototype.toString.call([value])
这四种方法各自有优缺点,其中Object.prototype.toString.call([value])是最为强大的,1和4是正经用来检测数据类型的,2.3就是后备的。接下来详细说说这四种方法的利弊和适用情况。

typeof

typeof是检测数据类型的运算符
1.返回结果是字符串,字符串中包含了所属的数据类型“number/function/boolean/string/object/undefined/bigInt”,所以 typeof typeof xxx 结果是‘’string‘’
2.缺点
不能细分对象是数组对象还是普通对象。
原理:按照计算机存储的二进制结果来检测,所有对象都是以000开头的,同时null的二进制是00000000,typeof null结果是object(null的类型就是null)

Instanceof

用来检测该实例是不是属于这个类,用它来检测,就是"临时凑数”的。它一般用来检测细分对象,比如普通对象/正则对象/日期对象/数组对象的检测。反正不好用。不支持原始数据类型,一般用来检测引用数据类型。
底层机制
基于“实例instanceof类”检测的时候,浏览器是这样处理的:类[Symbol.hasInstance](实例)
因为Function.prototype[Symbol.hasInstance]=function Symbol.hasInstance[native code].只有函数才有[Symbol.hasInstance]这个属性。
Symbol.hasInstance方法的执行原理:根据当前实例的原型链(_ proto_)是否有这个类的原型(prototype).

let arr = [12, 33]
console.log(arr.__proto__ == Array.prototype); //true
console.log(arr.__proto__.__proto__ == Object.prototype); //true

缺点:原型可以被改变,所以Instanceof不准。

constructor

原本是用来获取构造函数的,用来充当数据类型检测的,比Instanceof好用,但是存在致命问题,就是构造函数可以随意被更改。

Object.prototype.toString.call([value])

number/boolean/symbol/bigInt/function/array/date/regexp…等的原型上都有toString,是用来把这些数据类型转化为字符串的,但是object上的String是用来检测数据类型的。
返回结果:“[object,对象[Symbol.toStringTag] || 对象.构造函数 || object]”
其中的构造函数不会受自己更改的影响,对内置类有效。
最强大的检测方法,唯一的问题可能是有点长不好记忆。

bonus

重写instanceof

function _instanceof(obj, constructor) {
    if (obj == null || !/^(object|function)$/i.test(typeof obj)) return false;
    if (typeof constructor !== "function") throw new TypeError("Right-hand side of instanceof is not callable");
    let proto = Object.getPrototypeOf(obj), //Object.getPrototypeOf(obj)==obj.__proto__
        prototype = constructor.prototype;
    while (true) {
        if (proto == null) return false;
        if (proto == prototype) return true;
        proto = Object.getPrototypeOf(proto)
    }
}
console.log(_instanceof([], RegExp));//false
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值