• JS检测数据类型


      在Javascript应用场景中经常需要检测数据的类型。比如写一个简单的计算功能,你可能检测输入的参数是否是Number类型;在使用回调函数的时候,你可能要验证代表回调函数的那个值是不是function;再比如你想对某个对象执行深拷贝的时候,你可能需要判断拷贝对象的某些属性是不是Array类型。

      一些优秀的类库框架都会实现一些检测数据的函数,比如JQuery有isFunction、isArray等等,ExtJs也有类似的函数。

      今天来简单实现11个检测数据类型的函数。

    1.简述typeof操作符

      我们常常用typeof操作符来检测String、Undefined、Number、Boolean四种类型,因为用它检测这四种类型的结果是1对1的;其它结果如object、function对应的类型不唯一。

    //检测String、Number、Undefined、Boolean类型结果是可靠的
    console.log("undefined", typeof undefined);//undefined
    console.log("boolean", typeof false);//boolean
    console.log("number", typeof 1);//number
    console.log("string", typeof string);//string

      typeof 检测Null类型结果是object,检测对象字面量也会得到object结果。当使用它检测出object时,我们还需额外的检测逻辑才能具体确定数据类型。

    //我们还需要额外的逻辑才能进一步甄别null与对象字面量
    console.log("null", typeof null);//object
    console.log("{}", typeof {});//object
    console.log("正则", typeof (/[a]/g));//IE与Firefox返回Object、部分浏览器返回function

      typeof检测function类型时会得到function结果,但是Safari 5及之前的版本和Chrome 7及之前的版本中使用typeof检测正则表达式也会返回function结果。

      Ecma262规定任何内部实现[[Call]]函数的对象都应该在typeof操作中返回function,上述浏览器中正则表达式实现了该函数,所以导致返回function结果也会有不确定。

    2.简述instanceof操作符

      instanceof操作符我们通常用来检测构造器以之确定自定义引用类型。所以在一些框架类库中,检测自定义数据类型可以用它来实现内部逻辑。

    function A() {}
    function B() {}
    function C() {}
    C.prototype = new A();
    
    var c = new C();
    
    console.log("{} instanceof Object", {} instanceof Object);
    console.log("c instanceof A", c instanceof A);
    console.log("c instanceof B", c instanceof B);
    console.log("c instanceof Object", c instanceof Object);
    
    function isA(a) {
        return a instanceof A;
    }
    
    var b = new B();
    console.log(isA(c));//true
    console.log(isA(b));//false

      上面代码里我自定义了A、B、C三种类型,并且C使用原型链继承形式继承了A。所以在isA函数中检测c的实例得到true,而B的实例与A没继承关系,所以返回false。

      有一点值得注意的是instanceof也并不是绝对可靠。跨域通信场景中(frame框架),两个来自不同域相同实现的类型是无法检测出true的。

    3.简述Object.prototype.toString

      Object.prototype.toString常用来判断对象值属于哪种内置属性,它返回一个JSON字符串——"[object 数据类型]"。

      由于许多引用类型都重写了Object继承来的的toStrong方法,所以我们通常使用call或者apply借用Object.prototype.toString函数来判断数据类型。

      当然,这样调用的默认前提是Object.prototype.toString没有被重写。

    //定义toString变量是为了简便书写,同时降低作用域链检索的性能损耗
    var toString = Object.prototype.toString;
    console.log(toString.call(1));//[object Number]
    console.log(toString.call(undefined));//[object Undefined]
    console.log(toString.call(null));//[object Null]
    console.log(toString.call(false));//[object Boolean]
    console.log(toString.call("s"));//[object String]
    console.log(toString.call({}));//[object Object]
    console.log(toString.call(/[a]/g));//[object RegExp]
    console.log(toString.call(function(){}));//[object Function]

    4.is系列函数的简易实现

      在明白数据类型怎么检测后,下面我们来简单实现is系列检测函数。

    var dataType = {
            '[object Null]' : 'null',
            '[object Undefined]' : 'undefiend',
            '[object Boolean]' : 'boolean',
            '[object Number]' : 'number',
            '[object String]' : 'string',
            '[object Function]' : 'function',
            '[object Array]' : 'array',
            '[object Date]' : 'date',
            '[object RegExp]' : 'regexp',
            '[object Object]' : 'object',
            '[object Error]' : 'error'
        },
        toString = Object.prototype.toString;
    
    function type(obj) {
        return dataType[toString.call(obj)];
    }
    
    //生成is系列函数
    function createValidType() {
        for(var p in dataType) {
            var objType = p.slice(8, -1);
            (function(objType) {
                window['is' + objType] = function(obj) {
                    return type(obj) === objType.toLowerCase();
                }
            })(objType)
        }
    }
    createValidType();
    
    console.log(isObject({}));//true
    console.log(isDate(new Date()));//true
    console.log(isBoolean(false));//true
    console.log(isString(1));//false
    console.log(isError(1));//false
    console.log(isError(new Error()));//true
    console.log(isArray([]));//true
    console.log(isArray(1));//false

      上面代码里分别实现了isNull、isUndefined、isBoolean、isNumber、isString、isFunction、isArray、isDate、isRegExp、isObject、isError这11个检测函数。同时也实现了type函数,用以检测数据类型。

    console.log(type({}));//"object"
    console.log(type(new Date()));//"date"
    console.log(type(false));//"boolean"
    console.log(type(1));//"number"
    console.log(type(1));//"number"
    console.log(type(new Error()));//"error"
    console.log(type([]));//"array"
    console.log(type(1));//"number"

      createValidType函数巧用闭包保存数据状态的特性,批量生成is系列函数。

      至此,is系列检测函数简易实现完成。

      

      

      

      

  • 相关阅读:
    openOPC与监控页面二
    Node教程——Gulp前端构建工具-教程
    回到顶部插件
    《软件测试52讲》——测试基础知识篇
    计算贝塞尔曲线上点坐标
    少年,不要滥用箭头函数啊
    JS属性defer
    leetcode-572-另一个树的子树
    leetcode-9.-回文数
    leetcode-300-最长上升子序列
  • 原文地址:https://www.cnblogs.com/longhx/p/5408915.html
Copyright © 2020-2023  润新知