1、用typeof检测数据类型
console.log(typeof 2) // number
console.log(typeof true) // boolean
console.log(typeof 'str') // string
console.log(typeof []) // object
console.log(typeof function() {}) // function
console.log(typeof {}) // object
console.log(typeof undefined) // undefined
console.log(typeof null) // object
数组、对象、null都会被判断为object,其他判断都正确。
2、用instanceof检测数据类型
console.log(2 instanceof Number) // false
console.log(true instanceof Boolean) // false
console.log('str' instanceof String) // false
console.log([] instanceof Array) // true
console.log(function(){} instanceof Function) // true
console.log({} instanceof Object) // true
console.log(function(){} instanceof Object) // true
console.log([] instanceof Object) // true
instanceof内部运行机制是判断在其原型链中能否找到该类型的原型。
不能很好的判断基本数据类型。
而当判断引用类型时,数组、函数、对象都会被判断为Object类型,这里需要注意一下。
instanceof运算符可以用来测试一个对象,在其原型链中是否存在一个构造函数的prototype属性。
instanceof实现原理
function myInstanceof(theObject, aConstructor) {
// 获取对象的原型
let proto = Object.getPrototypeOf(theObject)
// 获取构造函数的 prototype 对象
let prototype = aConstructor.prototype
// 判断构造函数的 prototype 对象是否在对象的原型链上
while (true) {
if(!proto) return false;
if(proto === prototype) return true;
// 若未找到,则继续从其原型上找,Object.getPrototypeOf 方法用来获取执行对象的原型
proto = Object.getPrototypeOf(proto);
}
}
3、用constructor检测数据类型
console.log((2).constructor === Number) // true
console.log((true).constructor === Boolean) // true
console.log(('str').constructor === String) // true
console.log(([]).constructor === Array) // true
console.log((function(){}).constructor === Function) // true
console.log(({}).constructor === Object) // true
console.log((function(){}).constructor === Object) // false
console.log(([]).constructor === Object) // false
constructor有两个作用:
一是判断数据的类型,
二是对象实例通过constrcutor 对象访问它的构造函数。
注意:如果创建一个对象来改变它的原型,constructor就不能用来判断数据类型了。
function Fn(){};
Fn.prototype = new Array();
var f = new Fn();
console.log(f.constructor === Fn); // false
console.log(f.constructor === Array); // true
4、用Object.prototype.toString.call()检测数据类型
Object.prototype.toString.call() 使用 Object 对象的原型方法toString 来判断数据类型:
var a = Object.prototype.toString;
console.log(a.call(2)); // "[object Number]"
console.log(a.call(true)); // "[object Boolean]"
console.log(a.call('str')); // "[object String]"
console.log(a.call([])); // "[object Array]"
console.log(a.call(function(){})); // "[object Function]"
console.log(a.call({})); // "[object Object]"
console.log(a.call(undefined)); // "[object Undefined]"
console.log(a.call(null)); // "[object Null]"
同样是检测对象obj调用toString方法,
obj.toString()的结果和Object.prototype.toString.call(obj)的结果是不一样的。
这是因为toString是Object 的原型方法,而Array、function等类型作为Object的实例,都重写了toString方法。
不同的对象类型,调用toString 方法时,根据原型链的知识,调用的是对应的重写之后的toString方法。(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串等等,其他同理)
而不会去调用 Object 上原型toString 方法(返回对象的具体类型)。
所以采用 obj.toString()不能得到其对象类型,只能将obj转换为字符串类型。
因此,在想要得到对象的具体类型时,应该调用Object原型上的toString方法。