JS判断数据类型的方法

JS的数据类型分为基本类型和引用类型:
基本类型:String,Boolean,Number,Null,Undefined,Symbol(Symbol为ES6新增)
引用类型:Object(其中包含了Array,Date,Function等)数组

下面会介绍经常使用的四种判断方法app

  1. typeof
    typeof做为一个操做符,右边跟一个表达式,并返回这个表达式的数据类型。typeof A,判断A的数据类型
    对于基本类型,除了null都可返回正确的结果。
    对于引用类型,除了function可正确返回,其余的返回结果均为Object类型。
    所以若是对String,Boolean,NUmber,Undefined,Symbol,Function的类型判断能够用typeof
    如下为示例:框架

    //可返回想要的结果
    typeof "a" //"string"
    typeof true //"boolean"
    typeof 1 //"number"
    typeof undefined //"undefined"
    typeof Symbol() //"symbol"
    typeof function a(){} //"function"
    //不可返回想要的结果
    typeof null //object
    typeof [] //object
    typeof new Date() //object
  2. instanceof
    instanceof是用来检测构造函数的prototype属性是否出如今某个实例对象的原型链上,简而言之就是判断A是否为B的实例,A instanceof B,若是A是B的实例,则返回为true,不然返回为false
    对于基本类型,没法用instanceof正确判断。判断null和undefined会直接报错
    对于引用类型,也不够严谨。
    instanceof判断的是是否处于原型链上,而不是是否是处于原型 链最后一位,所以它并不能判断一个对象实例具体属于哪一种类型。例如 虽然instanceof能够判断出[]是Array的实例,但它认为[]也是 Object的实例,[],Array,Object在内部造成了一条原型链
    如下为示例:函数

    function A(){}
    var a = new A();
    a instanceof A;//true,由于A.prototype在a的原型链上
    1 instanceof Number //false
    "" instanceof String //false
    Symbol() instanceof Symbol //false
    true instanceof Boolean //false
    null instanceof Null
    VM137:1 Uncaught ReferenceError: Null is not defined
    at <anonymous>:1:17
    (anonymous) @ VM137:1
    undefined instanceof Undefined
    VM200:1 Uncaught ReferenceError: Undefined is not defined
    at <anonymous>:1:22
    (anonymous) @ VM200:1
    [] instanceof Array //true
    [] instanceof Object //true
    new Date() instanceof Date //true
    new Date() instanceof Object //true

    instanceof还有一个问题就是它假定只有一个全局执行环境,如 果网页中包含多个框架,那实际上就存在多个不一样全局执行环境,从而 存在两个不一样版本的构造函数,若是从一个框架向另外一个框架传入数 组,那么传入的数组与在第二个框架中原生态建立的数组分别具备各自 不一样的构造函数。
    如下为示例:spa

    var iframe=document.createElement("iframe")
    document.body.appendChild(iframe);
    iframeArray = window.frames[0].Array;
    var arr = new iframeArray(1,2);//[1,2]
    arr instanceof Array //false
    arr instanceof iframeArray //true

    针对这个问题,能够用ES5提供的Array.isArray()方法,它不会区分对象是在哪一个环境下建立的prototype

  3. constructorcode

    当一个函数被定义时,JS引擎会为它添加prototype原型,而后再在prototype上添加一个constructor属性,并让其指向函数的引用,以下图所示,咱们建立一个名为A的函数:
    QQ图片20200322221037.png
    当咱们new一个A的实例时,var a = new A();A被当成了构造函数,a是A的实例对象,此时A原型上的construct被传递到了A上,所以a.construct = A对象

    QQ图片20200322221026.png
    A利用原型对象上的construct引用了自身,当A做为构造函数来建立新的对象,原型上的construct属性就会被新建立的对象继承,从原型链角度讲,构造函数A就是新建立对象的数据类型,这样作的意义是,让新对象在生成时,都有可追溯的数据类型。一样,JS的内置对象在生成时也是这样的
    如下为示例,由于null和undefined时无效的对象,因此它们不会有constructor,因此会报错。blog

    "1".constructor == String //true
    true.constructor == Bollean // true
    Symbol().constuctor == Symbol // false
    [1].constructor == Array //true
    [1].constructor == Object //false
    new Date().constructor == Date //true
    new Function().constructor == Function //true
    1.constructor == Number
    VM505:1 Uncaught SyntaxError: Invalid or unexpected token
    VM587:1 Uncaught ReferenceError: Bollean is not defined
        at <anonymous>:1:21
    (anonymous) @ VM587:1
    null.constructor == NULL
    VM636:1 Uncaught TypeError: Cannot read property 'constructor' of null
        at <anonymous>:1:6
    (anonymous) @ VM636:1
    undefined.constructor == Undefined
    VM698:1 Uncaught TypeError: Cannot read property 'constructor' of undefined
        at <anonymous>:1:11
    (anonymous) @ VM698:1

    从示例中能够看出,彷佛咱们能够用construct判断String,Bollean,Array,Date,Function等,可是实际上函数的constructor是不稳定的,当被调函数的prototype被重写后,再次实例化,原有的constructor会变成Object,为了开发规范,在重写对象原型时,通常都须要从新给constructor赋值,以保证对象实例的类型不被更改。继承

    function A(){}
    a = new A()
    a.constructor == A //true
    A.prototype = {};
    b = new A();
    b.constructor == A //false
    b.constructor == Object //true
    a.constructor == Object //false
  4. Object.prototype.toString.call()
    这个方法时最准确最经常使用,每个继承Object的对象都有toString方法,若是toString方法没有被重写的话,会返回[Object type],其中type为对象的类型,但当除了Object类型的对象外,其余类型直接使用toString方法时,会直接返回都是内容的字符串,因此咱们须要call或者apply方法来改变toString方法的执行上下文,使用Object.prototype上的原生toString()方法判断数据类型。
    如下为示例:

    Object.prototype.toString.call() //"[object Undefined]"
    Object.prototype.toString.call("a") //"[object String]"
    Object.prototype.toString.call(true) //"[object Boolean]"
    Object.prototype.toString.call(1) //"[object Number]"
    Object.prototype.toString.call(1.1) //"[object Number]"
    Object.prototype.toString.call(null) //"[object Null]"
    Object.prototype.toString.call(undefined) //"[object Undefined]"
    Object.prototype.toString.call([1]) //"[object Array]"
    Object.prototype.toString.call(new Date()) //"[object Date]"
    Object.prototype.toString.call(Symbol()) //"[object Symbol]"
    Object.prototype.toString.call(function a(){}) //"[object Function]"
    Object.prototype.toString.call(new Function()) //"[object Function]"
相关文章
相关标签/搜索