# 比typeof运算符更准确的类型判断
不同数据类型的Object.prototype.toString方法返回值如下。
- 数值:返回[object Number]。
- 字符串:返回[object String]。
- 布尔值:返回[object Boolean]。
- undefined:返回[object Undefined]。
- null:返回[object Null]。
- 数组:返回[object Array]。
- arguments 对象:返回[object Arguments]。
- 函数:返回[object Function]。
- Error 对象:返回[object Error]。
- Date 对象:返回[object Date]。
- RegExp 对象:返回[object RegExp]。
- 其他对象:返回[object Object]。
这就是说,Object.prototype.toString可以看出一个值到底是什么类型。
Object.prototype.toString.call(2) // "[object Number]"
Object.prototype.toString.call('') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(Math) // "[object Math]"
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call([]) // "[object Array]"
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
利用这个特性,可以写出一个比typeof运算符更准确的类型判断函数。
var type = function (o){
    var s = Object.prototype.toString.call(o)
    return s.match(/\[object (.*?)\]/)[1].toLowerCase()
}
type({}); // "object"
type([]); // "array"
type(5); // "number"
type(null); // "null"
type(); // "undefined"
type(/abcd/); // "regex"
type(new Date()); // "date"
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
在上面这个type函数的基础上,还可以加上专门判断某种类型数据的方法。
var type = function (o){
  var s = Object.prototype.toString.call(o);
  return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};
['Null',
 'Undefined',
 'Object',
 'Array',
 'String',
 'Number',
 'Boolean',
 'Function',
 'RegExp',
 'Promise'
].forEach(function (t) {
  type['is' + t] = function (o) {
    if (t === 'Promise') { return Boolean(o && typeof o.then === 'function'); }
    return type(o) === t.toLowerCase();
  };
});
type.isObject({}) // true
type.isNumber(NaN) // true
type.isRegExp(/abc/) // true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Ts
export type Type = {
  isNull: (v: any) => boolean;
  isUndefined: (v: any) => boolean;
  isObject: (v: any) => boolean;
  isArray: (v: any) => boolean;
  isString: (v: any) => boolean;
  isNumber: (v: any) => boolean;
  isBoolean: (v: any) => boolean;
  isFunction: (v: any) => boolean;
  isRegExp: (v: any) => boolean;
  isPromise: (v: any) => boolean;
};
export type IsType =
  | 'null'
  | 'undefined'
  | 'object'
  | 'array'
  | 'string'
  | 'number'
  | 'boolean'
  | 'function'
  | 'regexp'
  | 'promise';
export const isType = function (o: any): IsType {
  const s = Object.prototype.toString.call(o);
  return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};
export const isNull = (v: any) => isType(v) === 'null';
export const isUndefined = (v: any) => isType(v) === 'undefined';
export const isObject = (v: any) => isType(v) === 'object';
export const isArray = (v: any) => isType(v) === 'array';
export const isString = (v: any) => isType(v) === 'string';
export const isNumber = (v: any) => isType(v) === 'number';
export const isBoolean = (v: any) => isType(v) === 'boolean';
export const isFunction = (v: any) => isType(v) === 'function';
export const isRegExp = (v: any) => isType(v) === 'regexp';
export const isPromise = (v: any) => Boolean(v && typeof v.then === 'function');
export const type: Type = {
  isNull,
  isUndefined,
  isObject,
  isArray,
  isString,
  isNumber,
  isBoolean,
  isFunction,
  isRegExp,
  isPromise,
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
