zoukankan      html  css  js  c++  java
  • javaScript系列 [32] type

    本文介绍 JavaScript 中的数据类型,以及这些数据的类型检测方式

    JavaScript 存在很多中数据类型,按照一贯的区分方式,我们把这些数据类型分为两大类,分别是原始(基本)数据类型和对象类型。

    其中基本( 原始 )数据类型有6种,分别是 null undefined boolean string number symbol,对象类型则为object,对象类型中包含Object、Array、RegExp、Function、Error、Set、Map、WeakMap等。

    在JavaScript 代码中我们经常需要对数据的类型进行检查,检查数据类型的方式主要有四种:

    • typeof 关键字
    • instanceof 关键字
    • Object.prototype.toString.call()
    • constructor 构造器属性

    typeof 关键字

    typeof 关键字是检查数据类型最简单也最常用的方法。

    console.log(typeof "abc")                   /* string */
    console.log(typeof 12345)                   /* number */
    console.log(typeof true)                    /* boolean */
    console.log(typeof undefined)               /* undefined */
    console.log(typeof Symbol())                /* symbol */
    console.log(typeof null)                    /* object */
    console.log(typeof typeof typeof Symbol())  /* string */
    
    console.log(typeof {})                      /* object */
    console.log(typeof [])                      /* object */
    console.log(typeof /abc/)                   /* object */
    console.log(typeof function(){})            /* function */
    

    我们在使用typeof 关键字的时候,有一些注意点。

    首先就是 typeof null 得到的结果为object 而非null,这在 JavaScript 语言中被认为(承认)是一个设计错误,typeof null 被判定为 object 的原因在于 null 本身表示什么都没有,所以在计算机中表示为一串0,而计算机内部处理的时候如果读取的数据总是以000开头,那么就将被认为是对象类型的数据。

    其次,typeof 关键字在对象类型进行运算的时候得到的都是object,只有函数类型比较特殊得到的是function,也就是说我们无法通过该关键字来检查给定的数据是否是数组、或者是正则表达式等等。如果需要获取这些结构的数据类型,或者说是获取这些数据的构造函数,常用的方式是借用 Object 原型对象上面的 toString 方法来实现,该方法总是会返回一个[object 构造函数]结构的字符串。

    Object.prototype.toString 方法

    JavaScript 语言中的Object.prototype.toString方法总是会返回[object 构造函数]结构的字符串,其中方括号中前面的object表明该数据是对象类型的,后面的则是创建该实例的构造函数。如果是一个普通的对象,譬如{name:"zs"},在调用该方法的时候 [代码为:({name:"zs"}).toString()]得到的结果为[object object], 但因为原型链方法覆盖的问题,数组或其它类型的数据则无法直接调用该方法。对于除普通对象外的其它对象类型的数据而言,它们需要通过 call 或 apply 绑定 this 的方式才能调用该方法。

    console.log(({}).toString())                              /* [object Object] */
    console.log(Object.prototype.toString.call({}))           /* [object Object] */
    console.log(Object.prototype.toString.call([]))           /* [object Array] */
    console.log(Object.prototype.toString.call(new Function)) /* [object Function]*/
    console.log(Object.prototype.toString.call(new RegExp))   /* [object RegExp] */
    console.log(Object.prototype.toString.call(new Error))    /* [object Error] */
    console.log(Object.prototype.toString.call(new Set))      /* [object Set] */
    console.log(Object.prototype.toString.call(new Map))      /* [object Map] */
    

    一般而言Object.prototype.toString 方法很好用,But 它也不是万能的,譬如它无法处理自定义类型的类型检查( 包括自定义构造函数 和 Class 等)。

    function Person() {};
    let p = new Person;
    
    class Animal {};
    let a = new Animal;
    console.log(Object.prototype.toString.call(p)) /* [object Object] */
    console.log(Object.prototype.toString.call(a)) /* [object Object] */
    

    对于自定义类型的数据,我们需要通过 instanceof 或者是 constructor 来进行检查。

    instanceof 关键字 && constructor 构造器属性

    JavaScript 语言中的 instanceof 关键字用于检查某个对象是否是指定构造函数创建的实例对象,在检查的时候会检查整条原型链。如果准确点说,那么instanceof 实际上检查的是某个对象( 左值 )是否在指定构造函数( 右值 )的原型链上面,如果在那么就返回 true ,否则的话就返回 false。

    console.log(p instanceof Person)                            /* true */
    console.log(a instanceof Person)                            /* false */
    console.log(a instanceof Animal)                            /* true */
    console.log(a instanceof Function, a instanceof Object)     /* false true */
    
    console.log(a.constructor == Person);                       /* false */
    console.log(a.constructor == Animal);                       /* true */
    console.log(a.constructor == Object);                       /* false */
    console.log(p.constructor == Person);                       /* true */
    
    console.log(({}).constructor == Object)                     /* true */
    console.log(([]).constructor == Array)                      /* true */
    

    这里试着给出instanceof关键字的实现代码,其实就是个死循环和循环内原型查找而已。

    /* instanceof 实现原理 */
    function mockInstanceof(instance,constructor){
    
      let B = constructor.prototype;
      let A = instance.__proto__;
    
      while(true)
      {
        /* Object.prototype.__proto__ -> null */
        if (A == null){
          return false;
        }
        if (A === B){
          return true;
        }
        A = A.__proto__;   
      }
    
    }
    
    /* 测试数据 */
    function Person() { };
    function Boy() { };
    let p = new Person;
    let b = new Boy;
    
    console.log(mockInstanceof(p, Person))          /* true */
    console.log(mockInstanceof(p, Object))          /* true */
    console.log(mockInstanceof(b, Boy))             /* true */
    console.log(mockInstanceof(b, Person))          /* false */
    
    
  • 相关阅读:
    利用jquery进行ajax提交表单和附带的数据
    jquery插件-validate
    function [eigf,eigv,dof]=laplaceeig(node,elem,problem)
    [A,D]=solverAdini(node,elem,bdEdge,h1,h2)
    Example11(June 9,2015)
    加州旅馆
    jpg/png格式图片转eps格式的方法--latex自带命令bmeps
    accumarray
    HDU 1423 最长公共字串+上升子序列
    HDU 1503 带回朔路径的最长公共子串
  • 原文地址:https://www.cnblogs.com/wendingding/p/15756499.html
Copyright © 2011-2022 走看看