数据类型检测的四种方式

作者: iceman_dev | 来源:发表于2017-03-04 12:23 被阅读640次

    一、typeof

    console.log(typeof 12); // number
    var str = 'iceman';
    console.log(typeof str); // string
    

    使用typeof检测数据类型,首先返回的都是一个字符串,其次字符串中包含了对应的数据类型,例如:"number"、"string"、"boolean"、"undefined"、"function"、"object"

    面试题:

    console.log(typeof typeof typeof function () {}); // string
    

    typeof的局限性:不能具体的细分是数组还是正则,还是对象中其他的值,因为使用typeof检测数据类型,对于对象数据类型中的所有的值,最后返回的结果都是"object"。

    应用一:添加默认值

    function fn(num1, num2) {
        // 方式一
        // if (typeof num2 === 'undefined') {
        //   num2 = 0;
        // }
    
        // 方式二:不适用fn(10,false)这种情况
        num2 = num2 || 0;
    }
    fn(10);
    

    应用二:回调函数调用

    function fn(callback) {
        //typeof callback === 'function' ? callback() : null;
        callback && callback();
    }
    fn(function () {
        
    });
    

    二、instanceof

    var ary = [];
    console.log(ary instanceof Array); // true
    console.log(ary instanceof Object); // true
    
    function fn() {}
    console.log(fn instanceof Function); // true
    console.log(fn instanceof Object); // true
    

    只要在当前实例的原型链上,用instanceof检测出来的结果都是true,所以在类的原型继承中,最后检测出来的结果未必是正确的,例如:

    function Fn() {
    }
    Fn.prototype = new Array; // 原型继承:让子类的原型等于父类的一个实例
    var f = new Fn;
    console.log(f instanceof Array); // true
    

    三、constructor

    constructor即构造函数,作用和instanceof非常的相似。

    var obj = [];
    console.log(obj.constructor === Array); // true
    console.log(obj.constructor === RegExp); // false
    

    constructor可以处理基本数据类型的检测

    var num = 1;
    console.log(num.constructor === Number); // true
    

    constructor检测Object和instanceof不一样,一般情况下是检测不了的

    var reg = /^$/;
    console.log(reg.constructor === RegExp); // true
    console.log(reg.constructor === Object); // false
    

    constructor的局限性:我们可以把类的原型进行重写,在重写的过程中,很有可能把之前的constructor给覆盖了,这样检测出来的结果就是不准确的。

    function Fn() {
    }
    Fn.prototype = new Array;
    var f = new Fn;
    console.log(f.constructor); // Array
    

    对于特殊的数据类型null和undefined,它们的所属类型是Null和Undefined,但是浏览器把这两个类保护起来了,不允许在外面访问使用。

    四、Object.prototype.toStrong.call()

    toString的理解:

    • 咋一看应该是转换为字符串,但是某些toString方法不仅仅是转换为字符串。对于Number、String、Boolean、Array、RegExp、Date、Function原型上的toString方法都是把当前的数据类转换为字符串的类型(它们的作用仅仅是用来转换为字符串的)

    • Object.prototype.toString并不是用来转换为字符串的。

    ({name:"iceman"}).toString() // --> "[object Object]"
     Math.toString() // --> "[object Math]"
    

    Number.prototype.toString是转换字符串的

    console.log((1).toString()); // --> Number.prototype.toString,--> "1"  转换为字符串
    console.log((1).__proto__.__proto__.toString()); // Object.prototype.toString --> "[object Object]"
    console.log((128).toString(2/8/10)); // 把数字转换为二进制/八进制/十进制
    

    Object.prototype.toStrong.call()是检测数据类型最准确最常用的方式,起原理为:

    • 先获取Object原型上的toString方法,让方法执行,并且改变方法中的this关键字的指向;

    • Object.prototype.toString 它的作用是返回当前方法的执行主体(方法中this)所属类的详细信息;

    var obj = {name:'iceman'};
    // toString中的this是obj,返回的是obj所属类的信息 --> "[object Object]"
    // 第一个object代表当前实例是对象数据类型的(这个是固定死的)
    // 第二个Object,代表的是obj所属的类是Object
    console.log(obj.toString());
    
    // toString中的this是Math,那么返回的是Math所属类的信息 --> "[object Math]"
    console.log(Math.toString());
    

    检测其他类型:

    var ary = [];
    console.log(Object.prototype.toString.call(ary)); // --> "[object Array]"
    console.log(Object.prototype.toString.call(/^$/)); // --> "[object RegExp]"
    console.log(({}).toString.call(1)); // --> "[object Number]"
    
    console.log(({}).toString.call('珠峰')); // --> "[object String]"
    console.log(({}).toString.call(true)); // --> [object Boolean]
    console.log(({}).toString.call(undefined)); // -->[object Undefined]
    console.log(({}).toString.call(null)); // -->[object Null]
    console.log(({}).toString.call(function () {})); // -->[object Function]
    

    实际使用:

    var ary = [];
    console.log(Object.prototype.toString.call(ary) === '[object Array]'); // true
    
    var reg = /^\[object Array\]$/;
    console.log(reg.test(Object.prototype.toString.call(ary))); // true
    

    检测原型继承的情况:

    function Fn() {
    }
    Fn.prototype = new Array;
    var f = new Fn;
    console.log(f instanceof Array); // true
    console.log(Object.prototype.toString.call(f) === '[object Array]'); // false
    

    个人公众号(icemanFE):分享更多的前端技术和生活感悟

    个人公众号.png

    相关文章

      网友评论

      本文标题:数据类型检测的四种方式

      本文链接:https://www.haomeiwen.com/subject/qhqxgttx.html