index.js
  1  var isBuffer = require('is-buffer');
  2  var toString = Object.prototype.toString;
  3  
  4  /**
  5   * Get the native `typeof` a value.
  6   *
  7   * @param  {*} `val`
  8   * @return {*} Native javascript type
  9   */
 10  
 11  module.exports = function kindOf(val) {
 12    // primitivies
 13    if (typeof val === 'undefined') {
 14      return 'undefined';
 15    }
 16    if (val === null) {
 17      return 'null';
 18    }
 19    if (val === true || val === false || val instanceof Boolean) {
 20      return 'boolean';
 21    }
 22    if (typeof val === 'string' || val instanceof String) {
 23      return 'string';
 24    }
 25    if (typeof val === 'number' || val instanceof Number) {
 26      return 'number';
 27    }
 28  
 29    // functions
 30    if (typeof val === 'function' || val instanceof Function) {
 31      return 'function';
 32    }
 33  
 34    // array
 35    if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) {
 36      return 'array';
 37    }
 38  
 39    // check for instances of RegExp and Date before calling `toString`
 40    if (val instanceof RegExp) {
 41      return 'regexp';
 42    }
 43    if (val instanceof Date) {
 44      return 'date';
 45    }
 46  
 47    // other objects
 48    var type = toString.call(val);
 49  
 50    if (type === '[object RegExp]') {
 51      return 'regexp';
 52    }
 53    if (type === '[object Date]') {
 54      return 'date';
 55    }
 56    if (type === '[object Arguments]') {
 57      return 'arguments';
 58    }
 59    if (type === '[object Error]') {
 60      return 'error';
 61    }
 62  
 63    // buffer
 64    if (isBuffer(val)) {
 65      return 'buffer';
 66    }
 67  
 68    // es6: Map, WeakMap, Set, WeakSet
 69    if (type === '[object Set]') {
 70      return 'set';
 71    }
 72    if (type === '[object WeakSet]') {
 73      return 'weakset';
 74    }
 75    if (type === '[object Map]') {
 76      return 'map';
 77    }
 78    if (type === '[object WeakMap]') {
 79      return 'weakmap';
 80    }
 81    if (type === '[object Symbol]') {
 82      return 'symbol';
 83    }
 84  
 85    // typed arrays
 86    if (type === '[object Int8Array]') {
 87      return 'int8array';
 88    }
 89    if (type === '[object Uint8Array]') {
 90      return 'uint8array';
 91    }
 92    if (type === '[object Uint8ClampedArray]') {
 93      return 'uint8clampedarray';
 94    }
 95    if (type === '[object Int16Array]') {
 96      return 'int16array';
 97    }
 98    if (type === '[object Uint16Array]') {
 99      return 'uint16array';
100    }
101    if (type === '[object Int32Array]') {
102      return 'int32array';
103    }
104    if (type === '[object Uint32Array]') {
105      return 'uint32array';
106    }
107    if (type === '[object Float32Array]') {
108      return 'float32array';
109    }
110    if (type === '[object Float64Array]') {
111      return 'float64array';
112    }
113  
114    // must be a plain object
115    return 'object';
116  };