[6a3a178] | 1 | var toString = Object.prototype.toString;
|
---|
| 2 |
|
---|
| 3 | module.exports = function kindOf(val) {
|
---|
| 4 | if (val === void 0) return 'undefined';
|
---|
| 5 | if (val === null) return 'null';
|
---|
| 6 |
|
---|
| 7 | var type = typeof val;
|
---|
| 8 | if (type === 'boolean') return 'boolean';
|
---|
| 9 | if (type === 'string') return 'string';
|
---|
| 10 | if (type === 'number') return 'number';
|
---|
| 11 | if (type === 'symbol') return 'symbol';
|
---|
| 12 | if (type === 'function') {
|
---|
| 13 | return isGeneratorFn(val) ? 'generatorfunction' : 'function';
|
---|
| 14 | }
|
---|
| 15 |
|
---|
| 16 | if (isArray(val)) return 'array';
|
---|
| 17 | if (isBuffer(val)) return 'buffer';
|
---|
| 18 | if (isArguments(val)) return 'arguments';
|
---|
| 19 | if (isDate(val)) return 'date';
|
---|
| 20 | if (isError(val)) return 'error';
|
---|
| 21 | if (isRegexp(val)) return 'regexp';
|
---|
| 22 |
|
---|
| 23 | switch (ctorName(val)) {
|
---|
| 24 | case 'Symbol': return 'symbol';
|
---|
| 25 | case 'Promise': return 'promise';
|
---|
| 26 |
|
---|
| 27 | // Set, Map, WeakSet, WeakMap
|
---|
| 28 | case 'WeakMap': return 'weakmap';
|
---|
| 29 | case 'WeakSet': return 'weakset';
|
---|
| 30 | case 'Map': return 'map';
|
---|
| 31 | case 'Set': return 'set';
|
---|
| 32 |
|
---|
| 33 | // 8-bit typed arrays
|
---|
| 34 | case 'Int8Array': return 'int8array';
|
---|
| 35 | case 'Uint8Array': return 'uint8array';
|
---|
| 36 | case 'Uint8ClampedArray': return 'uint8clampedarray';
|
---|
| 37 |
|
---|
| 38 | // 16-bit typed arrays
|
---|
| 39 | case 'Int16Array': return 'int16array';
|
---|
| 40 | case 'Uint16Array': return 'uint16array';
|
---|
| 41 |
|
---|
| 42 | // 32-bit typed arrays
|
---|
| 43 | case 'Int32Array': return 'int32array';
|
---|
| 44 | case 'Uint32Array': return 'uint32array';
|
---|
| 45 | case 'Float32Array': return 'float32array';
|
---|
| 46 | case 'Float64Array': return 'float64array';
|
---|
| 47 | }
|
---|
| 48 |
|
---|
| 49 | if (isGeneratorObj(val)) {
|
---|
| 50 | return 'generator';
|
---|
| 51 | }
|
---|
| 52 |
|
---|
| 53 | // Non-plain objects
|
---|
| 54 | type = toString.call(val);
|
---|
| 55 | switch (type) {
|
---|
| 56 | case '[object Object]': return 'object';
|
---|
| 57 | // iterators
|
---|
| 58 | case '[object Map Iterator]': return 'mapiterator';
|
---|
| 59 | case '[object Set Iterator]': return 'setiterator';
|
---|
| 60 | case '[object String Iterator]': return 'stringiterator';
|
---|
| 61 | case '[object Array Iterator]': return 'arrayiterator';
|
---|
| 62 | }
|
---|
| 63 |
|
---|
| 64 | // other
|
---|
| 65 | return type.slice(8, -1).toLowerCase().replace(/\s/g, '');
|
---|
| 66 | };
|
---|
| 67 |
|
---|
| 68 | function ctorName(val) {
|
---|
| 69 | return typeof val.constructor === 'function' ? val.constructor.name : null;
|
---|
| 70 | }
|
---|
| 71 |
|
---|
| 72 | function isArray(val) {
|
---|
| 73 | if (Array.isArray) return Array.isArray(val);
|
---|
| 74 | return val instanceof Array;
|
---|
| 75 | }
|
---|
| 76 |
|
---|
| 77 | function isError(val) {
|
---|
| 78 | return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number');
|
---|
| 79 | }
|
---|
| 80 |
|
---|
| 81 | function isDate(val) {
|
---|
| 82 | if (val instanceof Date) return true;
|
---|
| 83 | return typeof val.toDateString === 'function'
|
---|
| 84 | && typeof val.getDate === 'function'
|
---|
| 85 | && typeof val.setDate === 'function';
|
---|
| 86 | }
|
---|
| 87 |
|
---|
| 88 | function isRegexp(val) {
|
---|
| 89 | if (val instanceof RegExp) return true;
|
---|
| 90 | return typeof val.flags === 'string'
|
---|
| 91 | && typeof val.ignoreCase === 'boolean'
|
---|
| 92 | && typeof val.multiline === 'boolean'
|
---|
| 93 | && typeof val.global === 'boolean';
|
---|
| 94 | }
|
---|
| 95 |
|
---|
| 96 | function isGeneratorFn(name, val) {
|
---|
| 97 | return ctorName(name) === 'GeneratorFunction';
|
---|
| 98 | }
|
---|
| 99 |
|
---|
| 100 | function isGeneratorObj(val) {
|
---|
| 101 | return typeof val.throw === 'function'
|
---|
| 102 | && typeof val.return === 'function'
|
---|
| 103 | && typeof val.next === 'function';
|
---|
| 104 | }
|
---|
| 105 |
|
---|
| 106 | function isArguments(val) {
|
---|
| 107 | try {
|
---|
| 108 | if (typeof val.length === 'number' && typeof val.callee === 'function') {
|
---|
| 109 | return true;
|
---|
| 110 | }
|
---|
| 111 | } catch (err) {
|
---|
| 112 | if (err.message.indexOf('callee') !== -1) {
|
---|
| 113 | return true;
|
---|
| 114 | }
|
---|
| 115 | }
|
---|
| 116 | return false;
|
---|
| 117 | }
|
---|
| 118 |
|
---|
| 119 | /**
|
---|
| 120 | * If you need to support Safari 5-7 (8-10 yr-old browser),
|
---|
| 121 | * take a look at https://github.com/feross/is-buffer
|
---|
| 122 | */
|
---|
| 123 |
|
---|
| 124 | function isBuffer(val) {
|
---|
| 125 | if (val.constructor && typeof val.constructor.isBuffer === 'function') {
|
---|
| 126 | return val.constructor.isBuffer(val);
|
---|
| 127 | }
|
---|
| 128 | return false;
|
---|
| 129 | }
|
---|