- typeof 变量
返回一个字符串(小写),用来判断:Undefined, String, Number, Boolean, Symbol, Object, Function; 无法检测引用类型中的 Array;
优点:可以区分 Function 和 Object;
缺点:
- 对于 Null, 返回 Object 类型;
原因:Null 类型只有一个 null 值, 这个值表示一个空对象指针(出自JavaScript高级程序设计);
- 对于 Array, Date, RegExp 都会返回 Object, 不能更详细的区分;
typeof的检测原理:不同的对象在底层都表示二进制,在 JavaScript 中二进制前(低)三位存储其类型信息为:Object: 000, String: 100, Boolean: 110, Number: 1; null 的二进制表示全是 0,自然前三位也是 0,所以执行typeof时会返回Object;
console.log(typeof 8); // number
console.log(typeof "message"); // string
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
console.log(typeof getObj); // function
console.log(typeof getObj()); // object
console.log(typeof [1, 2, 3]); // object
console.log(typeof new Date()); // object
console.log(typeof new RegExp()); // object
- 变量 instanceof 变量
返回 true 或 false, 只能判断引用类型,无法检测基本类型;
判断原理:判断一个构造函数的prototype属性所指向的对象是否存在另外一个要检测对象的原型链上。简单来说:能验证 new 构造函数创建出来的实例,左边的对象是否是右边的类的实例,属于验证式判断类型;
缺点:只能判断两个对象是否属于实例关系,而不能判断一个对象实例具体属于什么类型(原型链上的都会返回true);console.log('message' instanceof String); // false
console.log(new String('message') instanceof String); // true
console.log(66 instanceof Number); // false
console.log(new Number(66) instanceof Number); // true
console.log(true instanceof Boolean); // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log({name:'赵云'} instanceof Object); // true
console.log(new Object({name:'赵云'}) instanceof Object);// true
console.log(['66','666'] instanceof Object); // true
console.log(new Array(['66','666']) instanceof Array); // true
console.log(function(){} instanceof Object); // true
console.log(function(){} instanceof Function); // true
console.log(new Function() instanceof Function); // true
console.log(new Date() instanceof Object); // true
console.log(new RegExp instanceof Object); // true
console.log(new String('message') instanceof Object); // true
console.log(new Number(66) instanceof Object); // true
- 变量.constructor === 变量
返回true或false
判断原理:当一个函数F被定义时,JS引擎会为F添加 prototype 原型,然后再在 prototype 上添加一个 constructor 属性,并让其指向F的引用;
具体来说:当 var f = new F() 时,F被当成了构造函数,f是F的实例对象,此时F原型上的 constructor 传递到了f上,因此f.constructor === F
缺点:
- 不能判断 Null, Undefind, 它们是无效对象,没有 constructor;
- constructor 是不稳定的,如:创建的对象更改了原型,无法检测到最初的类型;
console.log(''.constructor === String); //true
console.log(new Number(1).constructor === Number); //true
console.log([].constructor === Array); //true
console.log(true.constructor === Boolean); //true
console.log(new Function().constructor === Function); //true
console.log(new Date().constructor === Date); //true
console.log(document.constructor === HTMLDocument); //true
- Object.prototype.toString.call(变量)
返回'[object type]'(字符串),能判断所有类型,万能方法;
判断原理:JavaScript 中所有的对象都是继承 Object 对象的,通过 call 方法改变 this 指向,利用 Object.prototype 上的原生方法 toString 判断数据类型;console.log(Object.prototype.toString.call('message')); // [object String]
console.log(Object.prototype.toString.call(undefined)); // [object Undefined]
console.log(Object.prototype.toString.call(null)); // [object Null]
console.log(Object.prototype.toString.call(66)); // [object Number]
console.log(Object.prototype.toString.call(true)); // [object Boolean]
console.log(Object.prototype.toString.call({})); // [object Object]
console.log(Object.prototype.toString.call(function(){})); // [object Function]