常用的变量类型有11种:
Number,
String,
Boolean,
Object,
Array,
Json,
Function,
undefined,
Null,
Date,
RegExp,
Error
1、使用typeof能判断出四种,分别是number,string,boolean,object,剩余的均被检测为object
2、使用instanceof,根据instanceof的定义:判断参照对象的prototype属性所指向的对象是否在被行测对象的原型链上,这个定义比较绕,举个栗子:
class Person{
constructor(name){
this.name= name;
}
}
let p = new Person('张三')
console.log(p instanceof Person) //ture
按照定义描述就是Person的prototype属性所指向的原型对象是否存在于p的原型链中。
言归正传,这种变量判断可以检测出9种,undefined和null被检测为object,因为js中没有这种全局类型
但是这种方式判断有个弊端:
对于number,string,boolean这三种类型,
只有通过构造函数定义比如:
let num =new Number(1);
let str = new String('abc');
let bool = new Boolean(true);
这样定义才能检测出.
let num = 1;
let str = 'abc';
let bool = true;
这样定义是检测不出来的
3、使用constructor检测
针对于instanceof的弊端,我们使用constructor检测,constructor是原型对象的属性指向构造函数。
这种方式解决了instanceof的弊端,可以检测出除了undefined和null的9种类型
但是这种方式仍然有个弊端,就是constructor所指向的的构造函数是可以被修改的.
例如:
class Stuent = {
constructor(age){
this.age =age;
}
}
Student.prototype = new Person('张三')
Student.prototype.constructor === 'Person'//true
惊喜:如果想了解原型继承原理请移步阮一峰老师的面相对象编程.
4、使用Object.prototype.toString.call
Object.prototype.toString可以取得对象的内部属性[[class]],并根据这个内部属性返回诸如"[object Number]"的字符串.那么我们就可以通过call获取内部属性[[class]]
例如: Object.prototype.toString.call(num)//"[object Number]"
在ES5以及之前这种方式是唯一访问内部属性的方法,但是ES6已经废除了[[class]]的内部属性,取而待之的是internal solt
并且Object.prototype.toString执行步骤也发生了改变
惊喜:具体的对比点击打开链接
使用es6的话可以改变变量类型,两种方法
let obj = {}
(1) Object.defineProperty(obj,Symbol.toStringTag,{
get:function(){
return 'hello'
}
})
(2) Object.prototype[Symbol.toStringTag] = 'hello'
console.log(Object.prototype.toString.call(obj))//[object,hello]
5、使用jquery的$.type
其实$.type是基于ES5的Object.prototype.toString.call进一步封装.可以检测出所有的变量类型.