js中判断数据类型上

484 阅读4分钟

今天分享4种JavaScript类型判断的方法:typeof、instanceof、Object.prototype.toString.call()、constructor

JavaScript数据类型

JavaScript有八种内置类型,除对象外,其他统称为基本类型
空值 (null)
未定义 (undefined)
布尔值 (boolean)
数字 (number)
字符串 (string)
对象 (object)
符号 (symbol, ES6中新增)
大整数 (BigInt, ES2020 引入)
Symbol: 是ES6中引入的一种原始数据类型,表示独一无二的值。
BigInt:是 ES2020 引入的一种新的数据类型,用来解决 JavaScript中数字只能到 53 个二进制位(JavaScript 所有数字都保存成 64 位浮点数,大于这个范围的整数,无法精确表示的问题。具体可查看:新数据类型 — BigInt

typeof

typeof是一个操作符而不是函数,其右侧跟一个一元表达式,并返回这个表达式的数据类型。返回的结果用该类型的字符串(全小写字母)形式表示
包括以下 8 种string、number、boolean、undefined、function 、symbol、bigInt、object
对于数组,对象,null以及时间等数据,typeof只能返回object,而不能直接返回对应的类型,还需要通过其他法判断

console.log(typeof "");            // string
console.log(typeof 1 );            // number
console.log(typeof NaN );          // number
console.log(typeof true);          // boolean
console.log(typeof undefined);     // undefined
console.log(typeof function(){});  // function
console.log(typeof isNaN);         // function
console.log(typeof Symbol());      // symbol
console.log(typeof 123n);          // bigint
console.log(typeof []);            // object
console.log(typeof {});            // object
console.log(typeof null);          // object
console.log(typeof new Date());    // object
console.log(typeof new RegExp());  // object

instanceof

instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。
需特别注意:instanceof 检测的是原型 原型链上
即instanceof 用来比较一个对象是否为某一个构造函数的实例。
instanceof可以准确的判断复杂数据类型,但是不能正确判断基本数据类型。

console.log(12 instanceof Number);                 // false
console.log('22' instanceof String);               // false
console.log(true instanceof Boolean);              // false
console.log(null instanceof Object);               // false
console.log(undefined instanceof Object);          // false
console.log(function a() {} instanceof Function);  // true
console.log([] instanceof Array);                  // true
console.log({a: 1} instanceof Object);             // true
console.log(new Date() instanceof Date);           // true

Object.prototype.toString.call(o)

Object.prototype.toString(o)是 Object 的原型方法,
获取对象o的class属性。这是一个内部属性,
连接字符串:[object + 结果(1)],格式为 [object Xxx] ,其中 Xxx 就是对象的类型。
对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

console.log(Object.prototype.toString.call(1))          // [object Number]
console.log(Object.prototype.toString.call(1n))         // [object BigInt]
console.log(Object.prototype.toString.call('123'))      // [object String]
console.log(Object.prototype.toString.call(true))       // [object Boolean]
console.log(Object.prototype.toString.call(undefined))  // [object Undefined]
console.log(Object.prototype.toString.call(null))       // [object Null]
console.log(Object.prototype.toString.call({}))         // [object Object]
console.log(Object.prototype.toString.call([]))         // [object Array]
console.log(Object.prototype.toString.call(function a() {}))  // [object Function]
console.log(Object.prototype.toString.call(Symbol()))         // [object Symbol]
console.log(Object.prototype.toString.call(Math))             // [object Math]
console.log(Object.prototype.toString.call(JSON))             // [object JSON]
console.log(Object.prototype.toString.call(new Date()))       // [object Date]
console.log(Object.prototype.toString.call(new RegExp()))     // [object RegExp]
console.log(Object.prototype.toString.call(new Error))        // [object Error]
console.log(Object.prototype.toString.call(window)            // [object Window]
console.log(Object.prototype.toString.call(document))         // [object HTMLDocu]

//这是一个 案例了 
//以下是11种:
var number = 1;            // [object Number]
var string = '123';        // [object String]
var boolean = true;        // [object Boolean]
var und = undefined;       // [object Undefined]
var nul = null;            // [object Null]
var obj = {a: 1}           // [object Object]
var array = [1, 2, 3];     // [object Array]
var date = new Date();     // [object Date]
var error = new Error();   // [object Error]
var reg = /a/g;            // [object RegExp]
var func = function a(){}; // [object Function]
function checkType() {
    for (var i = 0; i < arguments.length; i++) {
        console.log(Object.prototype.toString.call(arguments[i]))
    }
}
checkType(number, string, boolean, und, nul, obj, array, date, error, reg, func)
//console.log(Object.prototype.toString.call(Math)); // [object Math]
//console.log(Object.prototype.toString.call(JSON)); // [object JSON]

constructor

JavaScript中,每个对象都有一个constructor属性,可以得知某个实例对象,到底是哪一个构造函数产生的, constructor属性表示原型对象与构造函数之间的关联关系。
当一个函数F被定义时,JS引擎会为F添加prototype原型,
然后在prototype上添加一个constructor属性,
并让其指向F的引用,F利用原型对象的constructor属性引用了自身,
当F作为构造函数创建对象时,原型上的constructor属性被遗传到了新创建的对象上,
从原型链角度讲,构造函数F就是新对象的类型。
这样做的意义是,让对象诞生以后,就具有可追溯的数据类型。
通过typeof运算符来判断它是原始的值还是对象。如果是对象,就可以使用constructor属性来判断其类型。
如判断数组的函数:

function isArray(data){ 
  return typeof data == "object" && data.constructor == Array; 
}
isArray([])  // true

判断是数组还是对象

//1. Array.isArray()
    console.log(Array.isArray(arr))      //数组返回true
//2. constructor
    console.log(arr.construtor === Array)//数据返回true
//3. Object.prototype.toString.call()
    console.log(Object.prototype.toString.call(arr)) //数组返回object Array

判断是不是一个空对象?

 //方法1 
    //通过for...in便利属性,如果是空对象返回false,否则返回true
            var Obj = function(obj){
                for(var item in obj){ 
                    return true;  
            }    
                    return false;
            }
    //方法2  es6新增的Object.keys()方法 
            var Obj = function(obj){
            if(Object.keys(obj).length == 0){
                return true     
            }else{
                return false   
            }
            }      
    //方法3
            function checkNullObj(obj) {
                 return Object.keys(obj).length === 0;
            }        

输入一个值 返回其数据类型 封装函数

    var a = "";
    function type(a){
        return Object.prototype.toString.call(a)
    }
    console.log(type(a))

判断是不是一个数组Array

    var a = [];
    console.log(a instanceof Array);    //Array 
    console.log(a.construtor == Array); //true