检测数据类型的方法有哪些?

576 阅读4分钟

数据类型包括:基本数据类型、引用数据类型。

基本数据类型:Null、undefined、String、Number、Boolean、Symbol

引用数据类型:Object、Array、Date、Function、Error、RegExp、Math、Number、String、Boolean、Globle

判断数据类型的方法主要有:typeof、intanceof、construtor、Object.prototype.toString.call( )、isArray(只能判断是否是数组)

推荐使用Object.prototype.toString.call( )


一、typeof (常用)

返回是一个字符串,常用于判断基本数据类型:String、Number、Undefined、Boolean、Function,但是对象和Null和数组返回Object。

console.log(typeof '');//string
console.log(typeof 1);//number
console.log(typeof true);//boolean
console.log(typeof undefined);//undefined
console.log(typeof function () { });//function
console.log(typeof {});//object
console.log(typeof null);//object
console.log(typeof [1,2,3]);//object

判断一个变量是否存在,可以使用typeof:

注意不能使用if(a),如果a未声明,会报错:a is not defined。

  if (typeof a != 'undefined') {
    console.log("a变量存在");
  } else {
    console.log("a变量不存在");
  }

//注意不能使用if(a),如果a未声明,会报错:a is not defined
 if (a) {
    console.log("1111");
  } else {
    console.log("222");
  }

二、instanceof

只适合用于检测引用类型,而不能检测基本的数据类型,返回的是一个布尔值。

只要在原型链上有构造函数都会返回true,使用instanceof检测不太准确。

instanceof的原理:

判断构造函数的原型链(prototype)属性是否出现在某实例的对象原型链上。

比如:A instanceof B 即B的prototype是否出现在A的原型链上。(A为实例对象,B为构造函数);

var arr = [];
console.log(arr);
console.log(arr instanceof Array);//true
console.log(arr instanceof Object);//true

let Person = function(){};
let p1 = new Person();
console.log(p1 instanceof Person);//true

let s1 = new String('leaf');
console.log(s1 instanceof String);//true

let str = "ice";
console.log(str instanceof String);//false

instanceof实现原理,可以参考:

// 思路:顺着原型查找,知道找到相同的原型对象,返回true 否则返回false
function myInstanceof(left, right) {
  // 使用typeof 判断基础数据类型
  if (typeof left !== 'object' || left === null) {
    return false;
  }
  // getPrototypeOf是Object对象自带的API,获取原型对象
  let proto = Object.getPrototypeOf(left);
  while (true) {
    if (proto === null) {
      return false;
    }
    // 找到相同原型对象,返回true
    if (proto === right.prototype) {
      return true
    }
    proto = Object.getPrototypeOf(proto);
  }
}

三、constructor(慎用!)

constructor这个属性存在构造函数的原型链上的属性,指向构造函数,可以通过直接访问查看构造函数上的__proto__直接查看所属类型。

var arr = [];
console.log(arr);
console.log(arr.constructor === Array);

因为原型链的属性是可以修改的,constructor会有被修改的可能,所以不建议使用该方法:

function Person(){

}

Person.prototype = new Array();//修改Person构造函数上原型链

var myFather = new Person();
console.log(Person.constructor === Array);//false

四、Object.prototype.toString.call( ) (推荐!!!)

返回一个“[object XXX]”格式的字符串,XXX就是具体的数据类型,包括:String,Number,Boolean,Undefined,Null,Function,Date,Array,RegExp,Error,HTMLDocument等。

toString是Object原型对象上的一个方法,该方法默认返回其调用者的具体类型,严格来说,是toString运行时this指向的对象类型,返回的类型。

let myNull = null;
console.log(Object.prototype.toString.call(myNull));//[object Null]

let myUndefined = undefined;
console.log(Object.prototype.toString.call(myUndefined));//[object Undefined]

let str = 'leaf';
console.log(Object.prototype.toString.call(str));//[object String]

let arr = [];
console.log(Object.prototype.toString.call(arr));//[object Array]

let boolean = true;
console.log(Object.prototype.toString.call(boolean));//[object Boolean]

let myDate = new Date();
console.log(Object.prototype.toString.call(myDate));//[object Date]

let myFun = function (){};
console.log(Object.prototype.toString.call(myFun));//[object Function]

let myError = new Error();
console.log(Object.prototype.toString.call(myError));//[object Error]

let myReg = /leaf/;
console.log(Object.prototype.toString.call(myReg));//[object RegExp]

最简单的判断是数组的方法,记住喽是object.prototype.toString.call()

五、isArray方法(只能判断数组)

isArray() 方法用于判断一个对象是否为数组。 如果对象是数组返回 true,否则返回 false。

const a = [];
const b = {};
Array.isArray(a);//true
Array.isArray(b);//false

六、相关面试题

实现一个全局通用的数据类型的判断方法

function getType(obj) {
  if (typeof obj !== 'object') {
    return (typeof obj)
  }
  return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');
}

console.log(getType([]));//Array
console.log(getType(null));//Null
console.log(getType('123'));//string

正则复习:
// ^ 匹配的开始
// $ 匹配输入的结束
// * 匹配前一个表达式0次或多次
// \s 匹配一个空白字符,包括空格、制表符、换页符、换行符等
// 正则表达式后的"g"是一个表示全局搜索选项或标记,将在整个字符串查找并返回所有匹配结果

如何判断一个数组?

判断数组的几种方法:

  • instanceof
  • 使用Array对象的isArray方法判断
  • Object.prototype.toString.call( )

1、instanceof

 if (arr instanceof Array === false) {
   console.log("非数组");
   return false
}
return true

2、使用Array对象的isArray方法判断

isArray() 方法用于判断一个对象是否为数组。

如果对象是数组返回 true,否则返回 false。

const a = [];
const b = {};
Array.isArray(a);//true
Array.isArray(b);//false

3、Object.prototype.toString.call( )

let arr = [];
if(Object.prototype.toString.call(arr) === "[object Array]"){
   console.log("我是数组");
  return true
}
console.log("我不是数组");
return false

如何判断一个空对象?

判断空对象的几种方法:

  • for...in遍历对象属性

  • 使用JSON.stringify

  • Object.keys( )

1、for...in遍历对象属性

let obj = {};

for (var i in obj) {// 如果不为空对象,会执行到这里,返回true
  return true
}
return false//如果空对象,返回false
}

2、使用JSON.stringify

let obj = {};

if (JSON.stringify(obj) === "{}") {
   return false
 }
return true //非空对象,返回true

3、Object.keys( )

ES5 引入了Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。

let obj = {};
console.log(Object.keys(obj));//[]

var obj = { foo: 'bar', baz: 42 };
console.log(Object.keys(obj));//["foo", "baz"]

可以通过判断返回数据的长度来知道它是否为空:

let obj = {};

if (Object.keys(obj).length === 0) {
  console.log("空对象");
  return false
}
return true

复习Object.keys( )的用法:

es6新增对象方法Object.keys.png

参考资料: