javascript中不同类型的区分
Value | function | typeOf |
"foo" | String | string |
new String("foo") | String | object |
1.2 | Number | number |
new Number(1.2) | Number | object |
true | Boolean | boolean |
new Boolean(true) | Boolean | object |
new Date() | Date | object |
new Error() | Error | object |
[1,2,3] | Array | object |
new Array(1, 2, 3) | Array | object |
new Function("") | Function | function |
/abc/g | RegExp | object |
new RegExp("meow") | RegExp | object |
{} | Object | object |
new Object() | Object | object |
null | Object | object |
undefined | undefined |
所有可以通过构造函数创建的对象都可以用 instanceof 检查类型
Object.prototype.toString.call(x) 来检查x的类型,可以区分Boolean, Number, String, Function, Array, Date, RegExp, Object, Error等等。
Javascript中有5种基本类型(除了symbol,es6中增加了symbol类型),以及对象类型,相信很多朋友像我一样,用了很久的js还是有点分不清怎么判断一个数据的类型。
typeof 运算符:
// Numbers
console.log(typeof 37 === 'number');
console.log(typeof 3.14 === 'number');
console.log(typeof Math.LN2 === 'number');
console.log(typeof Infinity === 'number');
console.log(typeof NaN === 'number'); // 尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字"
console.log(typeof Number(1) === 'number'); // 不要这样使用!
// Strings
console.log(typeof "" === 'string');
console.log(typeof "bla" === 'string');
console.log(typeof (typeof 1) === 'string'); // console.log(typeof返回的肯定是一个字符串
console.log(typeof String("abc") === 'string'); // 不要这样使用!
// Booleans
console.log(typeof true === 'boolean');
console.log(typeof false === 'boolean');
console.log(typeof Boolean(true) === 'boolean'); // 不要这样使用!
// Symbols
console.log(typeof Symbol() === 'symbol');
console.log(typeof Symbol('foo') === 'symbol');
console.log(typeof Symbol.iterator === 'symbol');
// Undefined
console.log(typeof undefined === 'undefined');
console.log(typeof blabla === 'undefined'); // 一个未定义的变量,或者一个定义了却未赋初值的变量
// Objects 使用Array.isArray或者Object.prototype.toString.call方法可以从基本的对象中区分出数组类型
console.log(typeof {a:1} === 'object');
console.log(typeof [1, 2, 4] === 'object');
console.log(typeof /[1]{5,20}$/ === 'object');
console.log(typeof {name:'wenzi', age:25} === 'object');
console.log(typeof null === 'object');//true
// 下面的容易令人迷惑,不要这样使用!
console.log(typeof new Boolean(true) === 'object');
console.log(typeof new Number(1) === 'object');
console.log(typeof new Date() === 'object');
console.log(typeof new String("abc") === 'object');
console.log(typeof new Error() === 'object');
// 函数
console.log(typeof function(){} === 'function');
console.log(typeof Math.sin === 'function');
通过上面例子我们可以很明显的看到,除了基本类型以外的类型,都是对象,但是有例外:null 的 typeof 值是 'object' 【坑1】, 函数的 typeof 值是 'function' ! (函数对象的构造函数是 Function,也就继承了 Function 的原型)【坑2】,NaN 的类型也是 'number'【坑3】
注意:本文的测试在现在最新浏览器上进行,老版本浏览器可能有所不同。比如Safari 3.X中typeof /^\d*$/;为'function'【坑4:兼容性复杂】。
不是所有对象都是返回 object,而且还有 null 捣乱,那我们如何判断一个值的类型呢
instanceof运算符: instanceof又叫关系运算符,可以用来判断某个构造函数的prototype属性是否存在另外一个要检测对象的原型链上
var str = new String("hello world");
console.log(str instanceof String);//true
console.log(String instanceof Function);//true
console.log(str instanceof Function);//false
constructor属性 在使用instanceof检测变量类型时,我们是检测不到number, 'string', bool的类型的
function Person(){
}
var Tom = new Person();
console.log(Tom.constructor === Person);//true
Object.prototype.toString.call
使用toString()方法来检测对象类型
function Type() { };
var toString = Object.prototype.toString;
console.log(toString.call(new Date) === '[object Date]');//true
console.log(toString.call(new String) ==='[object String]');//true
console.log(toString.call(new Function) ==='[object Function]');//true
console.log(toString.call(Type) ==='[object Function]');//true
console.log(toString.call('str') ==='[object String]');//true
console.log(toString.call(Math) === '[object Math]');//true
console.log(toString.call(true) ==='[object Boolean]');//true
console.log(toString.call(/[2]{5,20}$/) ==='[object RegExp]');//true
console.log(toString.call({name:'wenzi', age:25}) ==='[object Object]');//true
console.log(toString.call([1, 2, 3, 4]) ==='[object Array]');//true
//Since JavaScript 1.8.5
console.log(toString.call(undefined) === '[object Undefined]');//true
console.log(toString.call(null) === '[object Null]');//true
Array.isArray() 用于确定传递的值是否是一个 Array
// 下面的函数调用都返回 true
Array.isArray([]);
Array.isArray([1]);
Array.isArray(new Array());
// 鲜为人知的事实:其实 Array.prototype 也是一个数组。
Array.isArray(Array.prototype);
// 下面的函数调用都返回 false
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(17);
Array.isArray('Array');
Array.isArray(true);
Array.isArray(false);
Array.isArray({ proto: Array.prototype });
instanceof 和 isArray
当检测Array实例时, Array.isArray 优于 instanceof,因为Array.isArray能检测iframes.
通过如下代码可以创建该方法
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}