typeof:常用于判断基本数据类型,对于引用数据类型处除了function返回‘function’,其余都返回object;
typeof原理:不同的对象在底层都表示为二进制,在JavaScript中的二进制前(低)三位存储其类型信息。其中000表示对象;010表示浮点数;100表示字符串;110表示布尔值;1表示整数;
type null 为‘object’的原因:null的含义为空,二进制表示全为0,自然前三位就为000,所以会返回‘object’
console.log(typeof 'aaa');//string
console.log(typeof false);//boolean
console.log(typeof 1);//number
console.log(typeof null);//object
console.log(typeof undefined);//undefined
console.log(typeof function(){});//function
console.log(typeof [1,2,3]);//object
console.log(typeof {a:1});//object
instanceof:主要用于区分引用数据类型,检测方法是比较一个对象是否为某一个构造函数的实例,用其检测的结果都是返回true,不太适合用于简单数据类型的检测,检测过程繁琐且对于简单数据类型中的undefined、null、symbol检测不出来。
// instanceof 实现
function myInstanceof(L, R) {
const O = R.prototype;
if (L === null || L === undefined) return false
if (typeof L === 'object' || typeof L === 'function') {
L = L.__proto__;
while (true) {
if (L === null) {
return false
}
if (O === L) {
return true;
}
L = L.__proto__;
}
}else{
return false
}
}
console.log(myInstanceof([1, 2, 3], Array)); //true
console.log(myInstanceof(new Number(3),Number));//true
console.log(myInstanceof(3,Number));//false
console.log(myInstanceof(null,Object));//false
console.log(myInstanceof(undefined,Object));//false
console.log(null instanceof Object);//false
console.log(undefined instanceof Object);//false
console.log(3 instanceof Number);//false
console.log(new Number(3) instanceof Number);//true
缺点:1、不能检测基本数据类型;2、原型链可能被修改,导致结果不准确;3、只要能在原型链上找到构造函数,就返回TRUE,所以类型可能不准确;
console.log(1 instanceof Number) // false
console.log([] instanceof Array) // true
console.log([] instanceof Object) // true
Object.prototype.toString.call():适用于所有类型的判断检测,检测方法是Object.prototype.toString.call(数据)返回的是该数据的字符串。
var a = function () {
console.log('aaa');
}
var b = [1,2,3]
console.log(Object.prototype.toString(null));//'[object Object]'
console.log(Object.prototype.toString.call(null));//'[object Null]'
console.log(Object.prototype.toString(undefined));//'[object Object]'
console.log(Object.prototype.toString.call(undefined));//'[object Undefined]'
console.log(Object.prototype.toString(a));//'[object Object]'
console.log(Object.prototype.toString.call(a));//'[object Function]'
console.log(Object.prototype.toString(b));//'[object Object]'
console.log(Object.prototype.toString.call(b));//'[object Array]'
console.log(Object.prototype.toString.call('s'));//[object String]
console.log(Object.prototype.toString.call(1));//[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({}));//[object Object]
console.log(Object.prototype.toString.call([]));//[object Array]
console.log(Object.prototype.toString.call(function(){}));//[object Function]
console.log(Object.prototype.toString.call(Math));//[object Math]
console.log(Object.prototype.toString.call(window));//[object Window]
constructor:用于检测引用数据类型,检测方法是获取实例的构造函数判断和某个类是否相同,如果相同就说明该数据是符合那个数据类型,这种方法不会把原型链上的其他类也加进来,避免了原型链干扰。(null,undefined你没有构造函数,自然也就访问不到该属性,因此不能使用此属性来判断;constructor可以被改写,所以不一定准确)
console.log((1).constructor === Number);//true
console.log(([1,2,3]).constructor === Array);//true
console.log(null.constructor === Object);//TypeError 报错
console.log(undefined.constructor === Object);//TypeError 报错