zoukankan      html  css  js  c++  java
  • js中判断数据类型的4种方法

    js中数据类型有8种:

    基本数据类型(原始数据类型)(6种):

     number, string, boolean,null, undefined, symbol(es6新增)

    引用数据类型:

     object, function

     

    1. 最常用方法 -- typeof

    缺点: 不能细分对象,数组,时间对象

     typeof 运算符的最终结果有7(typeof null === 'object')

       "number" //   typeof 123 ; typeof NaN
       "string"    //   typeof "123"
       "boolean" //  typeof  true
       "function" //  function f() {}; typeof f
       "object"    //  typeof {}; typeof [];typeof new Date(); typeof null; typeof window  
       "undefined" // typeof undefined; typeof 未定义变量
       "symbol"  // typeof Symbol();

    2. 判断对象类型--instanceof

    instanceof 的原理是检查右边构造函数的prototype属性是否在左边实例对象的原型链上。

    instanceof(a, B) {// a代表实例对象;b代表构造函数
       a = a.__proto__;
       B = B.prototype;
       while(true) {
          if (a === null) {// 原型链顶层
              return false;
          }
          if(a === B) {
             return true;
          }
          a = a.__proto__;
       }
    }

    instanceof命令本质上调用的是构造函数上的静态方法[Symbol.hasInstance]。

    ⚠️:原生的构造函数该方法不能被覆写。

    可以通过在自定义的构造函数上添加静态方法[Symbol.hasInstance]自定义实现instanceof 命令。  

    class IsStr{
      static [Symbol.hasInstance](x) {
        return typeof x === 'string';
      }
    }
    console.log('' instanceof IsStr); //true

    所以下面的实例如果 instanceof Object 全部为true

        ([2]) instanceof Array  -> true
        (new Date()) instanceof Date -> true
        (function(){}) instanceof Function  -> true
        ({}) instanceof Object  -> true

        null,undefined 使用该运算法的时候,返回值永远是 false

    三 判断对象类型 constructor

       constructor属性的作用是,可以得知某个实例对象,到底是哪一个构造函数产生的。

        constructor属性是prototype对象上的属性,实例对象本身没有这个属性,调用的是原型对象上的constructor。

        因为js规定P.prototype.constructor === P

        (new Date()).constructor === Date  -> true
        ([2]).constructor === Array -> true
        (function(){}).constructor ===  Function  -> true
        ({}).constructor === Object  -> true

    ⚠️PS:instanceof 和 constructor 两者区别:

    instanceof考虑的是原型链

    function A(){};
    function B(){};
    A.prototype = new B(); // 构造函数A的原型是B的实例
    var aobj = new A(); 
    console.log(aobj.constructor === B) / //true
    console.log(aobj.constructor === A)  //false
    console.log(aobj instanceof A)          //true
    console.log(aobj instanceof B)          //true 

    类不通过prototype属性进行原型继承,es6的class中prototype是只读属性。

    class A {}
    Object.getOwnPropertyDescriptor(A, "prototype");
    /*
          { 
              "value": constructor,
              "writable": false,
              "enumerable": false,
              "configurable": false 
          }
    */
          class A{};
          class B{};
          A.prototype = new B();
          var aobj = new A(); 
          console.log(aobj.constructor === B)  //false
          console.log(aobj.constructor === A)  //true
          console.log(aobj instanceof A)       //true
          console.log(aobj instanceof B)       //false 

    四. 通用方法   

      缺点: 只能判断原生的数据类型,自定义的无法判断。

       Object.prototype.toString() 默认返回类型字符串。所有的值都继承该方法。

       但是数组、字符串、函数、Date 对象都又定义了属于自己的toString方法,覆盖了继承的Object.prototype的toString()方法。

       所以为了可以判断所有的类型,统一使用Object.prototype.toString.call(value),来判断数据类型。

       call方法是用于改变this的指向,value就是方法运行时的实例对象,如果value是原始值,会自动将其转为对应的包装对象。

    • 数值:返回[object Number]
    • 字符串:返回[object String]
    • 布尔值:返回[object Boolean]
    • undefined:返回[object Undefined]
    • null:返回[object Null]
    • 数组:返回[object Array]
    • arguments 对象:返回[object Arguments]
    • 函数:返回[object Function]
    • Error 对象:返回[object Error]
    • Date 对象:返回[object Date]
    • RegExp 对象:返回[object RegExp]
    • 其他对象:返回[object Object]。 

     *************判断一个变量是否是对象的方法*************

    function isObject(value) {
      return   value === Object(value)
    }
    // 注意,原始类型的值通过Object()函数之后,会变成对应的包装对象;
    // 对象(数组,对象,函数)等于本身

    **************************************************** 

  • 相关阅读:
    CAS在tomcat6.0.18下的SSO
    CAS在tomcat6.0.18下的SSO
    PL/SQL 0.几秒出结果,SQL效率一定高吗?
    优化大型复杂SQL
    C++ ProtoBuf小结
    protobuf c++入门
    Oracle_inner join,left join,right join,full join 的区别,用例子说明
    Linux_查看修改SWAP大小
    Oracle 优化器
    Oracle 行转列两种方法
  • 原文地址:https://www.cnblogs.com/lyraLee/p/10469772.html
Copyright © 2011-2022 走看看