index.js
1 var toString = Object.prototype.toString; 2 3 /** 4 * Get the native `typeof` a value. 5 * 6 * @param {*} `val` 7 * @return {*} Native javascript type 8 */ 9 10 module.exports = function kindOf(val) { 11 var type = typeof val; 12 13 // primitivies 14 if (type === 'undefined') { 15 return 'undefined'; 16 } 17 if (val === null) { 18 return 'null'; 19 } 20 if (val === true || val === false || val instanceof Boolean) { 21 return 'boolean'; 22 } 23 if (type === 'string' || val instanceof String) { 24 return 'string'; 25 } 26 if (type === 'number' || val instanceof Number) { 27 return 'number'; 28 } 29 30 // functions 31 if (type === 'function' || val instanceof Function) { 32 if (typeof val.constructor.name !== 'undefined' && val.constructor.name.slice(0, 9) === 'Generator') { 33 return 'generatorfunction'; 34 } 35 return 'function'; 36 } 37 38 // array 39 if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { 40 return 'array'; 41 } 42 43 // check for instances of RegExp and Date before calling `toString` 44 if (val instanceof RegExp) { 45 return 'regexp'; 46 } 47 if (val instanceof Date) { 48 return 'date'; 49 } 50 51 // other objects 52 type = toString.call(val); 53 54 if (type === '[object RegExp]') { 55 return 'regexp'; 56 } 57 if (type === '[object Date]') { 58 return 'date'; 59 } 60 if (type === '[object Arguments]') { 61 return 'arguments'; 62 } 63 if (type === '[object Error]') { 64 return 'error'; 65 } 66 if (type === '[object Promise]') { 67 return 'promise'; 68 } 69 70 // buffer 71 if (isBuffer(val)) { 72 return 'buffer'; 73 } 74 75 // es6: Map, WeakMap, Set, WeakSet 76 if (type === '[object Set]') { 77 return 'set'; 78 } 79 if (type === '[object WeakSet]') { 80 return 'weakset'; 81 } 82 if (type === '[object Map]') { 83 return 'map'; 84 } 85 if (type === '[object WeakMap]') { 86 return 'weakmap'; 87 } 88 if (type === '[object Symbol]') { 89 return 'symbol'; 90 } 91 92 if (type === '[object Map Iterator]') { 93 return 'mapiterator'; 94 } 95 if (type === '[object Set Iterator]') { 96 return 'setiterator'; 97 } 98 if (type === '[object String Iterator]') { 99 return 'stringiterator'; 100 } 101 if (type === '[object Array Iterator]') { 102 return 'arrayiterator'; 103 } 104 105 // typed arrays 106 if (type === '[object Int8Array]') { 107 return 'int8array'; 108 } 109 if (type === '[object Uint8Array]') { 110 return 'uint8array'; 111 } 112 if (type === '[object Uint8ClampedArray]') { 113 return 'uint8clampedarray'; 114 } 115 if (type === '[object Int16Array]') { 116 return 'int16array'; 117 } 118 if (type === '[object Uint16Array]') { 119 return 'uint16array'; 120 } 121 if (type === '[object Int32Array]') { 122 return 'int32array'; 123 } 124 if (type === '[object Uint32Array]') { 125 return 'uint32array'; 126 } 127 if (type === '[object Float32Array]') { 128 return 'float32array'; 129 } 130 if (type === '[object Float64Array]') { 131 return 'float64array'; 132 } 133 134 // must be a plain object 135 return 'object'; 136 }; 137 138 /** 139 * If you need to support Safari 5-7 (8-10 yr-old browser), 140 * take a look at https://github.com/feross/is-buffer 141 */ 142 143 function isBuffer(val) { 144 return val.constructor 145 && typeof val.constructor.isBuffer === 'function' 146 && val.constructor.isBuffer(val); 147 }