判断js中的数据类型有以下几种方法:
typeof、instanceof、constructor、prototype、$.type()/jquery.ytpe(),接下来主要比较以下这几种方法的异同。
1.最常见的判断方法:typeof
typeof运算符后可跟着一个操作数,用于判断该操作数的数据类型;typeof适用于数据类型中除null、object的其他5种类型的判断
typeof undefined; // "undefined";
typeof 1; // "number";
typeof '1'; // "string";
typeof true; // "boolean";
typeof Symbol(); // "symbol";
typeof {a : 1}; // "object";
typeof null === "object"; // true
typeof function () {} === "function"; // true
为什么typeof不可判断null:
在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null的类型标签也成为了 0,typeof null就错误的返回了"object"。
为什么typeof不可判断object:
函数是对象的子类型,按道理来说"typeof function () {} === 'object'"才对,但是结果却是"function"。这是因为,函数是一个“特殊的对象”,它特殊就特殊在它内部有一个属性[[call]],这个属性使它变成一个“可调用的对象”。而根据规范,实现了[[call]]属性的对象,typeof的结果是“function”
2.instanceof
typeof能判断一个数据是不是对象,却不能判断它是对象的哪个“子类型”,比如说不能判断是否为数组,是否为日期等。这个时候就可以用instanceof来进行判断了。但是,instanceof只能判断是否是你预期的类型且只能用于对象子类型的判断。
[1, 2] instanceof Array; // true
(function foo() {}) instanceof Function; // true
(new Date(2018)) instanceof Date; // true
(new Number(1)) instanceof Number; // true
(1) instanceof Number; // false
3.constructor
对于对象子类型的判断方法,除了用instanceof运算符来判断,还可以利用对象的constructor属性来进行判断。
({a:1}).constructor === Object; // true
([1,2]).constructor === Array; // true
(new Date(2018)).constructor === Date; // true
(function foo() {}).constructor === Function; // true
('1').constructor === String; // true
(1).constructor === Number; // true
(true).constructor === Boolean; // true
constructor属性不仅仅可以用于对象“子类型的判断”,还可以用于基本类型的判断。
constructor的值是对构造函数本身的引用,而不是函数名的字符串。也就是说constructor属性返回的是对象的构造函数,基本类型指向对应的内置对象的构造函数,如:Number、String、Date、Array等。注意,null和undefined没有构造函数。由于constructor是一个属性,所以一般情况下他的值是可以被任意修改。所以constructor虽然可以判断大部分的类型,但是无法判断null和undefined;而且由于它可以被修改,所以用constructor来判断数据的类型其实是不稳定且有些不可靠的。
4.prototype
完美的解决方案:利用“Object.prototype.toString.call('...')”来进行判断。
Object.prototype.toString.call('1'); // "[object String]"
Object.prototype.toString.call(1); // "[object Number]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call([1, 2, 3]); // "[object Array]"
Object.prototype.toString.call(function foo() {}); // "[object Function]"
Object.prototype属性表示Object的原型对象;toString()方法返回一个表示该对象的字符串;call用于指定this。所以使用Object.prototype.toString.call(date)会返回一个表示date的原型对象的字符串(如果date不是对象,会先转化为对象,null和undefined除外)
Object.prototype.toString虽然通用性强,但是相对来说比较繁琐,一般需要封装成函数进行调用才能进行判断(注意要严格区分大小写)
5.jquery.type
如果对象是undefined或null,则返回相应的“undefined”或“null”。
jQuery.type( undefined ) === "undefined"
jQuery.type() === "undefined"
jQuery.type( window.notDefined ) === "undefined"
jQuery.type( null ) === "null"