判断数据类型的方法

方法一:typeof

  • 语法:
    - typeof [需要检测的数据变量] 【返回被检测数据的类型名称】
  • 特点
    - 对于基本数据类型,除null外均可返回正确的结果
    - 对于引用数据类型,除function外均返回object类型
    - 对于null,返回object
    - 对于function返回function类型
        var str = '字符串类型';
        var num = 123;
        var bool = true;
        var bignum = BigInt("1234567890123456789012345678901234567890");
        var d = undefined;
        var n = null;
        var s = Symbol('foo');

        var obj = { a: 1 };
        var arr = [1, 2];
        
        console.log(typeof str);//String
        console.log(typeof num);//Number
        console.log(typeof bool);//Boolean
        console.log(typeof bignum);//BigInt
        console.log(typeof d);//Undefined
        console.log(typeof n);//Object
        console.log(typeof s);//Symbol
        console.log(typeof obj);//Object
        console.log(typeof arr);//Object

方法二:instanceof(检测某一个实例的原型链上是否有这个类的原型属性)

  • 语法:[检测数据] instanceof [class] 返回true或false
  • 特点:
    - 可以区分复杂数据类型
    - 只要在当前实例的原型链上,我们就用其检测出来的结果都是true
    - 基本类型值检测繁琐,且检测不全(undefined、null、symbol)
  • 原理:验证当前类的原型prototype是否会出现在实例的原型链proto上,只要在它的原型链上,则结果都为true。因此,instanceof在查找的过程中会遍历左边变量的原型链,直到找到右边变量的prototype,找到返回true,未找到返回false。

1、检测复杂数据类型

        // 可以区分复杂数据类型
        console.log([] instanceof Array); //true
        console.log({} instanceof Object); //true

2、检测基本数据类型
在检测基本数据类型时,需要将基本数据类型进行包装
比如:数据类型 1 变成数据包装类型 new Number(1)
字符串 ‘1’ 变成字符串包装类型 new String(1)
布尔值 true 变成布尔包装类型 new Boolean(true)
null、undefined、symbol没有数据包装类型

  • 数据类型、字符串、布尔值用instanceof检测
        // 基本类型值(number, string, boolean)转成包装类型才能进行检测
        console.log(1 instanceof Number); // false
        console.log(new Number(1) instanceof Number); // true
        console.log('1' instanceof String); // false
        console.log(new String('1') instanceof String); // true
        console.log(true instanceof Boolean); // false
        console.log(new Boolean(true) instanceof Boolean); // true
  • null、undefined、symbol没有数据包装类型
        // 没有包装类型的基本类型值(undefined, null, symbol)无法检测
        // console.log(undefined instanceof Undefined); // Uncaught ReferenceError: Undefined is not defined
        console.log(undefined instanceof Object); // Uncaught ReferenceError: Null is not defined
        // console.log(null instanceof Null); // false
        console.log(null instanceof Object); // false
        console.log(Symbol('1') instanceof Symbol); // false
        console.log(Symbol('1') instanceof Object); // false

3、在检测复杂数据类型时,在原型链上类的也会被检测为true

        // 可以检测原型链上所有类
        console.log([] instanceof Object); // true
        console.log(new Date() instanceof Object);// true
        function Person() { }
        console.log(new Person() instanceof Person); // true

4、手写实现instaceof方法
原理:既然原型链上的类都会被检测,那就是一直检测实例对象上的原型上的类,与右边的类的prototype上的类名进行比对。

        function myinstanceOf_(left, right) {
            let proto = left.__proto__;
            let prototype = right.prototype
            while (true) {
                if (proto == null) return false
                if (proto == prototype) return true
                proto = proto.__proto__;
            }
        }

方法三:Object.prototype.toString.call()(对象原型链判断方法)

  • 语法:Object.prototype.toString.call(监测数据)
  • 特点:适用于所有类型的判断检测
  • 原理:Object.prototype.toString()表示一个返回对象类型的字符串,call()方法 可以改变this的指向,那么把Object.prototype.toString()方法指向不同的数据类型上面,返回不同的结果
console.log(typeof Object.prototype.toString(111)) //string
        console.log(Object.prototype.toString.call("123"))   // --------> [object String]
        console.log(Object.prototype.toString.call(123))     //--------> [object Number]
        console.log(Object.prototype.toString.call(true))    //--------> [object Boolean]
        console.log(Object.prototype.toString.call([1, 2, 3])) //--------> [object Array]
        console.log(Object.prototype.toString.call(null))      //--------> [object Null]
        console.log(Object.prototype.toString.call(undefined)) //--------> [object Undefined]
        console.log(Object.prototype.toString.call({ name: 'Hello' })) //--------> [object Object]
        console.log(Object.prototype.toString.call(function () { }))   //--------> [object Function]
        console.log(Object.prototype.toString.call(new Date()))        //--------> [object Date]
        console.log(Object.prototype.toString.call(/\d/))              //--------> [object RegExp]
        console.log(Object.prototype.toString.call(Symbol()))          //--------> [object Symbol]

方法四:constructor(用于引用数据类型)

  • 语法:检测数据.constructor === class
  • 特点:
    - 适合使用在引用数据类型上
    - 原型链不会干扰
  • 原理:构造函数原型上有一个constructor属性指向构造函数自身的,如果在实例上使用constructor时,就会直接使用其构造函数原型上的该属性,并指向其构造函数。

比如:[]的构造函数属性里面包含了构造函数array。
在这里插入图片描述

        // 可以检测其构造函数
        console.log([].constructor === Array); // true
        console.log({}.constructor === Object);// true
        function Person() { }
        console.log(new Person().constructor === Person);// true

        // 原型链不会干扰
        console.log([].constructor === Object); // false
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐