| var toString = Object.prototype.toString; |
| |
| /** |
| * Get the native `typeof` a value. |
| * |
| * @param {*} `val` |
| * @return {*} Native javascript type |
| */ |
| |
| module.exports = function kindOf(val) { |
| var type = typeof val; |
| |
| // primitivies |
| if (type === 'undefined') { |
| return 'undefined'; |
| } |
| if (val === null) { |
| return 'null'; |
| } |
| if (val === true || val === false || val instanceof Boolean) { |
| return 'boolean'; |
| } |
| if (type === 'string' || val instanceof String) { |
| return 'string'; |
| } |
| if (type === 'number' || val instanceof Number) { |
| return 'number'; |
| } |
| |
| // functions |
| if (type === 'function' || val instanceof Function) { |
| if (typeof val.constructor.name !== 'undefined' && val.constructor.name.slice(0, 9) === 'Generator') { |
| return 'generatorfunction'; |
| } |
| return 'function'; |
| } |
| |
| // array |
| if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { |
| return 'array'; |
| } |
| |
| // check for instances of RegExp and Date before calling `toString` |
| if (val instanceof RegExp) { |
| return 'regexp'; |
| } |
| if (val instanceof Date) { |
| return 'date'; |
| } |
| |
| // other objects |
| type = toString.call(val); |
| |
| if (type === '[object RegExp]') { |
| return 'regexp'; |
| } |
| if (type === '[object Date]') { |
| return 'date'; |
| } |
| if (type === '[object Arguments]') { |
| return 'arguments'; |
| } |
| if (type === '[object Error]') { |
| return 'error'; |
| } |
| if (type === '[object Promise]') { |
| return 'promise'; |
| } |
| |
| // buffer |
| if (isBuffer(val)) { |
| return 'buffer'; |
| } |
| |
| // es6: Map, WeakMap, Set, WeakSet |
| if (type === '[object Set]') { |
| return 'set'; |
| } |
| if (type === '[object WeakSet]') { |
| return 'weakset'; |
| } |
| if (type === '[object Map]') { |
| return 'map'; |
| } |
| if (type === '[object WeakMap]') { |
| return 'weakmap'; |
| } |
| if (type === '[object Symbol]') { |
| return 'symbol'; |
| } |
| |
| if (type === '[object Map Iterator]') { |
| return 'mapiterator'; |
| } |
| if (type === '[object Set Iterator]') { |
| return 'setiterator'; |
| } |
| if (type === '[object String Iterator]') { |
| return 'stringiterator'; |
| } |
| if (type === '[object Array Iterator]') { |
| return 'arrayiterator'; |
| } |
| |
| // typed arrays |
| if (type === '[object Int8Array]') { |
| return 'int8array'; |
| } |
| if (type === '[object Uint8Array]') { |
| return 'uint8array'; |
| } |
| if (type === '[object Uint8ClampedArray]') { |
| return 'uint8clampedarray'; |
| } |
| if (type === '[object Int16Array]') { |
| return 'int16array'; |
| } |
| if (type === '[object Uint16Array]') { |
| return 'uint16array'; |
| } |
| if (type === '[object Int32Array]') { |
| return 'int32array'; |
| } |
| if (type === '[object Uint32Array]') { |
| return 'uint32array'; |
| } |
| if (type === '[object Float32Array]') { |
| return 'float32array'; |
| } |
| if (type === '[object Float64Array]') { |
| return 'float64array'; |
| } |
| |
| // must be a plain object |
| return 'object'; |
| }; |
| |
| /** |
| * If you need to support Safari 5-7 (8-10 yr-old browser), |
| * take a look at https://github.com/feross/is-buffer |
| */ |
| |
| function isBuffer(val) { |
| return val.constructor |
| && typeof val.constructor.isBuffer === 'function' |
| && val.constructor.isBuffer(val); |
| } |