最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JavaScript 高阶版「检测数据类型方法」

    正文概述 掘金(Guyal_)   2021-03-01   566

    检测数据类型的方法

    typeof 底层原理及优缺点

    typeof 类型检测

    1. 检测原始值类型
    typeof null; 'object'
    typeof undefined;'undefined'
    typeof 1/-1;'number'
    typeof NaN;'number'
    typeof Infinity;'number'
    typeof true;'boolean'
    typeof 'guyal';'string'
    typeof ''; 'string'
    typeof Symbol();'symbol'
    typeof 10n;'bigint'
    
    1. 对象类型
    typeof {} 'object'
    typeof [] 'object'
    typeof /^$/ 'object'
    
    1. 函数
    typeof function(){}; 'function'
    

    typeof 底层原理

    • 计算机底层都是通过二进制来进行数据存储的,以不同的数字开头代表不同的数据类型,比如:
      • 1:数字
      • 010:浮点数
      • 100:字符串
      • 110:布尔
      • 000:对象
      • -2^30:undefined
    • JS 设计上的缺陷
      • 凡是以 000 开始的都认为是对象,null 是 000000,所以误认为 null 是 object 类型 「这是 JS 设计的缺陷」

    typeof 特点

    • typeof null 的结果是:'object'
    • typeof 实现 call 的对象,比如:函数,箭头函数、生成器函数、构造函数..,其结果是:'function';其余未实现 call 的对象,结果是:'object'
    • 检测出来的结果是字符串,字符串的内容就是数据对应的类型
    • 检测原始值类型还是比较简单方便的

    typeof 缺点

    • 对于对象数据类型,检测出来的结果都是 'object',函数是'function'
    • 因为 typeof 检测是基于构造函数创建出来的,基本数据类型的实例对象,也是一个对象:'object',所以使用 typeof 检测出来的对象类型是:object 类型

    typeof null 的结果为什么是 object 类型

    计算机底层都是根据二进制来存储数据的,以 000 开头的代表对象,而 null 是 000000,计算机误认为是对象,所以,typeof 的检测结果是'object'

    instanceof 原理及优缺点

    instanceof 用途

    • 主业:检测某个实例是否属于某个类
    • 副业:数据类型检测「可以细分出部分对象的类型」

    instanceof 使用范围

    • 基本类型值和 Symbol 类型不能使用「本身不是对象,没有__proto__ 属性」
    • 但是,可以检测基于构造函数创建出来的基本类型对象值

    instanceof 底层原理

    • 内置原理:
      • 通过类的 Symbol.hasInstance 属性来实现的
      • Symbol.hasInstance:用于判断对象是否为构造器的实例
    • 底层原理:
      • 首先查找 Symbol.hasInstance,如果存在那么就会基于这个属性检测,如果不存在,则基于原型链 proto 查找,只要构造器的 prototype 出现在实例的原型链上,那么结果就为 true;
      • 长话短说:检测当前构造函数的原型 prototype,是否出现在实例的原型链上,如果有,结果就是 true;

    instanceof 存在的问题

    • 只能基于 class 方式构建 Symbol.hasInstance

    方法才会生效:

    static [Symbol.hasInstance](实例) {
        return Array.isArray(实例)
    }
    
    • 所有实例的原型链最终都会指向 Object.prototype,所以:实例 instanceof Object 的结果都为 true
    • 在原生 JS 中,原型链都是可以随意改动的,所以,检测出来的结果是不准确的
    • 字面量方式创建的基本数据类型值不能通过 instanceof 方法检测:浏览器不会默认把原始值转换为 new 的方式,所以本身不是对象,不存在__proto__ 属性
    • 不能检测原始值类型

    重写 instanceof

    Symbol.hasInstance

    Object.getPropertyOf

    
    // 重写 instanceof 方法
    function my_instanceOf(exam, ctor) {
        let exam_ = typeof exam,
            ctor_ = typeof ctor;
        // 必须保证构造器是一个函数
        if (ctor_ !== 'function' || !ctor.prototype) throw new TypeError(ctor+'is not an constructor') 
    
        // 排除 null、undefined
        if(exam == null) return false;
        // 排除原始值
        if (!/^(object|function)$/i.test(exam_) ) return false;
    
        // 条件都可满足
        // 检测是否存在 [Symbol.hasInstance]()
        if (typeof ctor[Symbol.hasInstance] === 'function'){
            return ctor[Symbol.hasInstance](exam)
        }
    
        // 不存在 [Symbol.hasInstance](),基于原型链机制检测
        let proto = Object.getPrototypeOf(exam);
    
        while (proto) {
            // 判断 proto 与 ctor.prototype 是否相等
            if(proto === ctor.prototype) return true;
            proto = Object.getPrototypeOf(proto);
        }
        return false;
    }
    console.log(my_instanceOf([], Array)); //->true
    console.log(my_instanceOf([], RegExp)); //->false
    console.log(my_instanceOf([], Object)); //->true
    

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

    检测范围

    • Number.prototype
    • String.prototype
    • Symbol.prototype
    • BigInt.prototype
    • Array.prototype
    • RegExp.prototype
    • Function.prototype

    返回值

    • 大部分内置类的原型上都有 toString,一般都是转换为字符串,只有 Object.prototype 上的 toString 并不是转换为字符串,而是返回当前实例对象所属类的信息的:'[object 所属类的构造函数信息]'

    内置原理

    • 所属类的构造函数信息是根据 Symbol.toStringTag 获取的
    • 有这个属性基于这个获取的,没有则是浏览器自己计算的
    • toString() 找不到 toStringTag 属性时只好返回默认的 Object

    Object.prototype.toString.call 是检测数据类型方式的万全之策

    constructor

    constructor 是可以肆意被修改的,所以也不准,这里就不多说了。

    以上内容,如有错误之处,请给予指正!感谢~
    

    起源地下载网 » JavaScript 高阶版「检测数据类型方法」

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元