JavaScript判断数据类型的方式
- typeof
- instanceof
- constructor
- Object.prototype.toString.call()
typeof 方式
原理:通过数据在计算机存储的二进制来判断数据类型
console.log(typeof 111); //number
console.log(typeof NaN); //number
console.log(typeof 'a'); //string
console.log(typeof true);//boolean
console.log(typeof undefined); //undefined
console.log(typeof null); //object
console.log(typeof {}); //object
console.log(typeof []); //object
console.log(typeof /^$/); //object
console.log(typeof Function); //function
优缺点
- 对基本数据类型的检测比较友好
- 检测
普通对象、数组对象、正则对象、日期对象
都返回object
类型。 - 检测
null
返回object
类型
手写typeof函数
// 手写typeof
function type_of(exp){
let str = exp.constructor.toString()
let expClass = str.slice(9,str.indexOf('(')).toLowerCase()
return expClass
}
console.log(type_of(1));//number
instanceof 方式
检测当前实例是否属于这个类(弥补typeof对对象类型
的不友好)
底层机制:只要当前类出现在实例的原型链上,结果都是true
let arr = []
console.log(arr instanceof Array); //true
console.log(arr instanceof Object); //true
let obj = {}
console.log(obj instanceof Object); //true
let reg = /^$/
console.log(reg instanceof RegExp); //true
console.log(1 instanceof Number); //false
console.log('a' instanceof String); //false
console.log(true instanceof Boolean);//false
问题
- 由于我们可以修改数据原型的指向,所以检测出来的结果也是不一定的
- 不能检测基本数据类型
手写instanceof函数
// 手写instanceof
function instance_of(exp, classFunc) {
// 获取类的原型
let classFuncPrototype = classFunc.prototype
// 获取实例的原型 exp.__proto__
let proto = Object.getPrototypeOf(exp)
// 获取实例原型链
while (true) {
if(proto === null) return false
if(proto === classFuncPrototype) return true
proto = Object.getPrototypeOf(proto)
}
}
console.log(instance_of(arr,Object));
constructor 方式
虽然看起来好像比instanceof
好用(支持基本类型),但是constructor
也是可以随便改。
let arr = []
console.log(arr.constructor === Array);
let n = 1
console.log(n.constructor === Number);
let str = ''
console.log(str.constructor === String);
Object.prototype.toString.call() 方式
标准检测数据类型的方法
toString()方法的执行,this指向什么类型就会返回什么类型
console.log(Object.prototype.toString.call(''));
console.log(Object.prototype.toString.call(true));
console.log(Object.prototype.toString.call(undefined));
console.log(Object.prototype.toString.call(null));
console.log(Object.prototype.toString.call({}));
console.log(Object.prototype.toString.call([]));
console.log(Object.prototype.toString.call(/^$/));
console.log(Object.prototype.toString.call(NaN));
Jquery判断类型的源码
(function () {
var classZtype = {}
var toString = classZtype.toString // Object.prototype.toString
// 设置数据类型映射
let type = ['Boolean', 'Number', 'String', 'Functions', 'Array',
'Date', 'RegExp', 'Object', 'Error', 'Symbol']
type.forEach(name => {
classZtype[`[object ${name}]`] = name.toLowerCase()
})
function toType(obj) {
if (obj == null) {
// 传递的值是null或者undefined,就返回对应字符串
return obj + ""
}
// 基本数据类型都采用typeof检测
return typeof obj == "object" || typeof obj === "function" ?
classZtype[toString.call(obj)] || "object" : typeof obj
}
window.toType = toType
})()
console.log(toType(1));
console.log(toType(''));
console.log(toType([]));