index.js (3562B)
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 }