js数据类型及其检测

  • 基本数据类型

    • number(特殊值:NaN、infinity)

      if("haha" == NaN) {
          // 条件是否成立?
          //注意 NaN != NaN 它和谁都不相等
      }
      
    • string

    • boolean

    • null(null == undefined,但是和其它值都不相等)

    • undefined

    • symbol

    • bigint

  • 引用数据类型

    • object(普通对象、数组对象、正则对象、日期对象、math数学函数对象...)
    • function(每个function都是Function的实例对象)

数据类型检测

  • typeof 检测数据类型的逻辑运算符

    • 返回当前值的数据类型,返回结果都是字符串

    • 局限性:

      • typeof null => "object"

        js中的数据在底层是以二进制存储,如果前三位为0,那么就会判定为object,而null的所有都为0 ,所以null会被检测为object

      • typeof 不能细分对象类型(检测普通对象或者数组对象等都是"object")

  • instanceof 检测是否为某个类的实例

    • 原理

      只要右边变量的 prototype 在左边变量的原型链上即可。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false,告诉我们左边变量并非是右边变量的实例

    • 代码实现

      function new_instance_of(leftVaule, rightVaule) { 
          let rightProto = rightVaule.prototype; // 取右表达式的 prototype 值
          leftVaule = leftVaule.__proto__; // 取左表达式的__proto__值
          while (true) {
          	if (leftVaule === null) {
                  return false;	
              }
              if (leftVaule === rightProto) {
                  return true;	
              } 
              leftVaule = leftVaule.__proto__ 
          }
      }
      
    • 局限性:

      只要在这个实例的原型链上的类,用instanceof检测的时候都为true,因此在类的继承中,我们只是单纯通过instanceof来检测数据类型的话是不准确的

  • constructor 检测构造函数

    ary.constructor===Array //true 
    //说明ary是Array这个类的一个实例
    
    • 局限性:

      constructor可以让用户自己来修改,所以我们一般不用这个来检测

  • Object.prototype.toString.call 检测数值的数据类型(常用而且相对来说精准的检测方式 )

    • 原理

      在Object.prototype上有一个toString方法,这个方法执行的时候,会返回方法中this关键字对应数据值的数据类型,例如:

      //Object.prototype.toString() ->返回的是 Object.prototype 的数据类型 ->"[object Object]"
      //f.toString() ->返回的是f的数据类型 ->"[object Object]"
      
    • 这样的话,我们就可以让Object.prototype.toString执行,并且通过call/apply来改变里面的this关键字,也就是想检测谁的数据类型,我们就可以让this变为谁

      Object.prototype.toString.call(12) ->检测12的数据类型 ->"[object Number]"
      Object.prototype.toString.call("zhufeng") ->"[object String]"
      Object.prototype.toString.call(null) ->"[object Null]"
      Object.prototype.toString.call(undefined) ->"[object Undefined]"
      Object.prototype.toString.call([]) ->"[object Array]"
      Object.prototype.toString.call(/^$/) ->"[object RegExp]"
      Object.prototype.toString.call(function(){}) ->"[object Function]"
      

把其他数据类型转换为数字的方法

  • 强转换(基于底层机制转换的) Number([value])

    • 一些隐式转换都是基于Number完成的
      • isNaN('12px') //先把其它类型值转换为数字再检测
      • 数学运算 '12px' - 13
      • 字符串 == 数字
      • ...
  • 弱转换(基于一些额外的方法转换) parseInt([value]) / parseFloat([value])

    console.log(parseFloat("long200"))
    //NaN
    //从字符串的第一个字符开始查找 是数字就继续查找 不是就结束
    
  • 注意:

    1. parseInt 处理的值是字符串,从字符串的左侧开始查找有效数字字符(遇到非有效数字字符则停止查找),如果处理的值不是字符串,需要先转换为字符串然后再开始查找接口

    2. Number 直接调用浏览器最底层的数据类型检测机制来完成

      • true 1 false 0
      • null 0 undefined NaN
      • Number([])、Number('') 0
      • 字符串中必须保证都是有效数字才会转换为数字,否则都为NaN
      parseInt("") //NaN
      Number("")  //0
      isNaN("") //先把""转换为数字0,再判断 false
      parseInt(null) //parseInt('null') NaN
      Number(null) //0
      isNaN(null) //isNaN(0) false
      
posted @ 2021-03-22 20:43  Hhhighway  阅读(55)  评论(0)    收藏  举报