• js关于精确判断数据类型的总结


    先定义以下初始变量

    ar num = 123;
    var str = 'abcdef';
    var bool = true;
    var arr = [1, 2, 3, 4];
    var obj = {name:'wenzi', age:25};
    var func = function(){ console.log('this is function'); }
    var und = undefined;
    var nul = null;
    var date = new Date();
    var reg = /^[a-zA-Z]{5,20}$/;
    var error= new Error();

    1. 使用typeof检测

    console.log(
        typeof num,  // number
        typeof str,  // string
        typeof bool,  // boolean
        typeof arr,  // object
        typeof obj,  // object
        typeof func,  // function
        typeof und,  // undefined
        typeof nul,  // object
        typeof date,  // object
        typeof reg,  // object
        typeof error // object
    );

    从输出结果可以看出arr, json, nul, date, reg, error 全部被检测为object类型,其他的变量能够被正确检测出来。当需要变量是否是number, string, boolean, function, undefined类型时,可以使用typeof进行判断。其他引用类型以及null是判断不出类型的

    2. 使用instanceof检测

    首先instanceof能检测出继承

    function Person(){}
    function Student(){}
    Student.prototype = new Person();
    var John = new Student();
    console.log(John instanceof Student); // true
    console.log(John instancdof Person); // true

    其次可以判断引用类型

    console.log(
        num instanceof Number, // false
        str instanceof String, // false
        bool instanceof Boolean,  // false
        arr instanceof Array, // true--注意
        arr instanceof Object, // true--注意
        obj instanceof Object,  // true--注意
        func instanceof Function,  // true
        und instanceof Object, // false
        nul instanceof Object, // false
        date instanceof Date,  // true
        reg instanceof RegExp, // true
        error instanceof Error // true
    )

    从结果可以看出instanceof不能判断值类型,但是引用类型可以,值得注意的是arr和obj在instanceof Object的时候的值都是true,这就导致判断是对象时不准确

    原因是如下

    [].__proto__ === Array.prototype // true
    Array.prototype.__proto__ === Object.prototype // true

    3. 使用constructor检测

    constructor本来是原型对象上的属性,指向构造函数。但是根据实例对象寻找属性的顺序,若实例对象上没有实例属性或方法时,就去原型链上寻找,因此,实例对象也是能使用constructor属性的

    function Person(){}
    var Tom = new Person();
    // undefined和null没有constructor属性
    console.log(
        Tom.constructor==Person,
        num.constructor==Number,
        str.constructor==String,
        obj.constructor==Boolean,
        arr.constructor==Array,
        json.constructor==Object,
        func.constructor==Function,
        date.constructor==Date,
        reg.constructor==RegExp,
        error.constructor==Error
    );
    // 所有结果均为true

    表面上看很完美,但是有两个缺点

      1).undefined和null没有constructor属性,所以判断时可能会报错--这就直接导致代码运行不下去了,所以只有在确定待判断的值不是undefined和null才能使用

      2).由于constructor属性是可以变更的,也会导致检测出的结果不正确

    4. 使用Object.prototype.toString.call -- 目前通用的办法

    console.log(
        Object.prototype.toString.call(num),  // '[object Number]'
        Object.prototype.toString.call(str),  // '[object String]'
        Object.prototype.toString.call(bool),  // '[object Boolean]'
        Object.prototype.toString.call(arr),  // '[object Array]'
        Object.prototype.toString.call(obj),  // '[object Object]'
        Object.prototype.toString.call(func),  // '[object Function]'
        Object.prototype.toString.call(und),  // '[object Undefined]'
        Object.prototype.toString.call(nul),  // '[object Null]'
        Object.prototype.toString.call(date),  // '[object Date]'
        Object.prototype.toString.call(reg),  // '[object RegExp]'
        Object.prototype.toString.call(error)  // '[object Error]'
    );

    ECMA里规范定义了Object.prototype.toString的行为:首先,取得对象的一个内部属性[[Class]],然后依据这个属性,返回一个类似于”[object Array]”的字符串作为结果(看过ECMA标准的应该都知道,[[]]用来表示语言内部用到的、外部不可直接访问的属性,称为“内部属性”)。利用这个方法,再配合call,我们可以取得任何对象的内部属性[[Class]],然后把类型检测转化为字符串比较,以达到我们的目的。

  • 相关阅读:
    使用Dorado框架开发必备参考
    Dorado重用最佳实践
    css布局_web
    dorado学习笔记(二)
    Oracle归档日志删除
    给大家拜年啦!
    悟透JavaScript
    BCM57781网卡驱动下载地址
    win7安装jdk完后配置
    win7删除SVN保存的本地密码
  • 原文地址:https://www.cnblogs.com/zhujunislucky/p/14581269.html
Copyright © 2020-2023  润新知