四种数据类型检测 typeof instanceof constructor Object.prototype.toString().call()使用方法、区别

54 阅读2分钟
说到数据类型检测,首先我们先来了解JS的基本数据类型和引用数据类型

JS的基本数据类型:Number、String、null、undefined、boolean、Symbol(ES6)、bigInt 引用数据类型:object、function、Date、Array、regexp(正则)等

①使用typeof检测

使用方法:typeof(operand)

//基本数据类型
console.log(typeof 1) //number
console.log(typeof 'abc') //string
console.log(typeof null) //object
console.log(typeof undefined) // undefined
console.log(typeof true) //boolean
console.log(typeof Symbol(1)) //symbol
//引用数据类型
console.log(typeof console.log)//function
console.log(typeof {}) //object
console.log(typeof []) //object
console.log(typeof new Date())//object
console.log(typeof new RegExp())//object

虽然typeof nullobject,但这只是JS的一个 Bug,不代表null就是引用数据类型,并且null本身也不是对象,所以如果要判断null的类型的话不能使用typeof!!

我们可以看到typeof可以检测出基本数据类型,但引用类型只能识别出function,其余无法准确的检测出引用类型。

②使用instanceof检测

instanceof主要用来检测构造函数的 prototype 属性是否出现在某个实例对象的原型链

使用方法:object(某个实例对象) instanceof constructor(某个构造函数)

let Car = function() {}
let Benz = new Car()
console.log(Benz instanceof Car) // true
var newstr = new String('nihaoya~')
console.log(newstr instanceof String) //true
var againstr = 'nihaoya'
console.log(againstr instanceof String) //false
let arr = [1,2,3]
console.log(arr instanceof Array) //true
console.log(arr instanceof Object) //true
console.log(arr.__proto__ === Array.prototype)//true
console.log(arr.__proto__.__proto__ === Object.prototype) //true

从上面的代码可以看出,arr数组既属于Array 又属于 Object。这是因为insetanceof的定义,是用来检测构造函数的 prototype 属性是否出现在某个实例对象的原型链。每一个对象上都有一个__proto__属性,指向创建该对象的函数的peototype属性。instanceof的判断是通过 prototype 和 prpto 能否找到同一个引用对象。

我们可以看到instanceof虽然能够检测引用数据类型,但是却不能准确检测基础数据类型,且返回的值是布尔值,不是数据的类型。

③constructor

使用方法:object.constructor == Constructor

image.png

用法我觉得跟instanceof差不多

首先我们定义一个函数的时候,该函数对象的prototype上有constructor属性,指向A的引用。当我们实例化一个对象的时候,此时A原型上的constructor传递到了a上,因此a.constructor == A

console.log('abc'.constructor == String); //true
console.log(new Number(123).constructor == Number); //true
console.log(true.constructor == Boolean); //true
console.log(Symbol(1).constructor == Symbol); //true

console.log([1,2,3].constructor == Array); //true
console.log({}.constructor == Object); //true
console.log(function A(){}.constructor == Function); //true
console.log(new Date().constructor == Date); //true
console.log(new RegExp().constructor == RegExp) //true


// console.log(null.constructor == null); 报错
// console.log(undefined.constructor == undefined); 报错 

返回结果也是布尔值,但是我们可以发现,用nullundefined如果用constructor检测会报错,因为这两个数值是无效值,没有constructor

前三种方法不能够很好的检测出每个数据类型,接下来介绍的这种方法基本上所有对象的类型都可以通过这个方法获取到。

④object.prototype.toString.call()

使用方法:object.prototype.toString.call(operand)

console.log(Object.prototype.toString.call('abc')); //[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(null)); //[object Null]
console.log(Object.prototype.toString.call(undefined)); //[object Undefined]
console.log(Object.prototype.toString.call(Symbol(1))); //[object Symbol]
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(new Date())); //[object Date]
console.log(Object.prototype.toString.call(new RegExp())); //[object RegExp]