index.js 3.1 KB

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