超详细!检测数据类型常见的四种方法是什么?他们的区别是什么?

/*
 * 数据类型检测:
 *   + typeof
 *     typeof [value] -> 返回一个字符串,其次字符串中包含了对应的数据类型   
 *     特点:
 *       @1 typeof null -> "object"
 *       @2 typeof不能细分对象类型,除函数对象会返回“function”,检测其余对象都是返回“object”
「含:非标准特殊对象 new Number(1) 等」  
 *       @3 基于typeof检测一个未被声明的变量,结果不会报错,而是“undefined”
 *     原理:
 *       所有数据类型值,在计算机底层都是基于“二进制”形式进行存储的「64位」,而typeof就是基于存储
的二进制值进行检测的「好处:性能好」,它会识别二进制值的前三位数字:如果前三位数字都是0,就会按对象
处理「识别为对象后,再看对象有没有实现[[call]]方法,实现了这个方法则被解析为“function”,否则都是
“object”...」;而null存储的二进制值是64个零,前三位也是零,所以也被识别为“object”!!
 *     应用:
 *       @1 检测除了null以外的原始值类型、检测函数类型,优先选择基于typeof检测
 *          if(obj!==null && /^(object|function)$/i.test(typeof obj)){
 *              //obj是对象或者函数
 *          }
 *       @2 检测JS代码运行的环境「浏览器(webview)、webpack、node...」
 *          if(typeof window!=="undefined"){
 *              //浏览器或者webpack环境
 *          }
 *          if(typeof module==="object" && typeof module.exports==="object"){
 *              //支持CommonJS模块规范的环境「webpack、node」
 *          }
 *        ...
 * 
 *   + instanceof
 *     [实例] instanceof [构造函数] -> 检测当前实例是否属于这个构造函数(类)
 *     特点:
 *       @1 instanceof不支持原始值类型的检测,检测出来的结果都是false
 *       @2 可以检测一些 标准特殊对象、非标准特殊对象、函数对象 等;但是不能有效区分是否为标准普
通对象(纯粹的对象 -> 例如:{} 直接是Object类的实例 对象.__proto__===Object.prototype),因为所
有对象都是Object类的实例,基于instanceof检测结果都是true!!
 *       @3 检测结果仅供参考「因为原型链是可以被修改的,这样实例和构造函数间的关系也会被修改」
 *       instanceof本身就不是检测数据类型的,非要拿来用,那么结果就可想而知了...
 *     原理:
 *       [实例] instanceof [构造函数],首先检测 “[构造函数][Symbol.hasInstance]” 这个属性是否
存在「在兼容ES6语法的浏览器中,Function.prototype[Symbol.hasInstance] 具备这个属性方法」,如
果具备这个属性,则处理机制 “[构造函数][Symbol.hasInstance]([实例])” ... 如果不具备这个方法,则
基于[实例]的原型链一层层向上查找,只要[构造函数]出现在其原型链上结果就是true,反之是false...
 * 
 *   + constructor
 *     [实例].constructor===[构造函数]
 *     也不准确:因为constructor值是可以被肆意修改的
 *     
 *   + Object.prototype.toString.call([value]) 检测[value]的数据类型
 *     基本上所有数据类型所属构造函数的原型上都有toString方法,而一般都是用来转换为字符串的!除
了 Object.prototype.toString 是用来检测数据类型的!
 *     @1 只要把Object.prototype.toString方法执行,方法中的this指向谁,就是检测谁的数据类型
 *     @2 检测的结果 “[object ?]”  ?的取值
 *        + 先看 “[value][Symbol.toStringTag]” 属性是否存在,如果存在,则属性值是啥,?就是啥
 *        + 如果不存在,则按照[value]内部的[[class]]值(所属构造函数)处理
 *   ---
 *   Array.isArray([value]) 检测[value]是否是一个数组
 *   isNaN([value]) 检测是否为有效数字
 */

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值