You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.5 KiB
129 lines
3.5 KiB
var toString = Object.prototype.toString; |
|
|
|
module.exports = function kindOf(val) { |
|
if (val === void 0) return 'undefined'; |
|
if (val === null) return 'null'; |
|
|
|
var type = typeof val; |
|
if (type === 'boolean') return 'boolean'; |
|
if (type === 'string') return 'string'; |
|
if (type === 'number') return 'number'; |
|
if (type === 'symbol') return 'symbol'; |
|
if (type === 'function') { |
|
return isGeneratorFn(val) ? 'generatorfunction' : 'function'; |
|
} |
|
|
|
if (isArray(val)) return 'array'; |
|
if (isBuffer(val)) return 'buffer'; |
|
if (isArguments(val)) return 'arguments'; |
|
if (isDate(val)) return 'date'; |
|
if (isError(val)) return 'error'; |
|
if (isRegexp(val)) return 'regexp'; |
|
|
|
switch (ctorName(val)) { |
|
case 'Symbol': return 'symbol'; |
|
case 'Promise': return 'promise'; |
|
|
|
// Set, Map, WeakSet, WeakMap |
|
case 'WeakMap': return 'weakmap'; |
|
case 'WeakSet': return 'weakset'; |
|
case 'Map': return 'map'; |
|
case 'Set': return 'set'; |
|
|
|
// 8-bit typed arrays |
|
case 'Int8Array': return 'int8array'; |
|
case 'Uint8Array': return 'uint8array'; |
|
case 'Uint8ClampedArray': return 'uint8clampedarray'; |
|
|
|
// 16-bit typed arrays |
|
case 'Int16Array': return 'int16array'; |
|
case 'Uint16Array': return 'uint16array'; |
|
|
|
// 32-bit typed arrays |
|
case 'Int32Array': return 'int32array'; |
|
case 'Uint32Array': return 'uint32array'; |
|
case 'Float32Array': return 'float32array'; |
|
case 'Float64Array': return 'float64array'; |
|
} |
|
|
|
if (isGeneratorObj(val)) { |
|
return 'generator'; |
|
} |
|
|
|
// Non-plain objects |
|
type = toString.call(val); |
|
switch (type) { |
|
case '[object Object]': return 'object'; |
|
// iterators |
|
case '[object Map Iterator]': return 'mapiterator'; |
|
case '[object Set Iterator]': return 'setiterator'; |
|
case '[object String Iterator]': return 'stringiterator'; |
|
case '[object Array Iterator]': return 'arrayiterator'; |
|
} |
|
|
|
// other |
|
return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); |
|
}; |
|
|
|
function ctorName(val) { |
|
return typeof val.constructor === 'function' ? val.constructor.name : null; |
|
} |
|
|
|
function isArray(val) { |
|
if (Array.isArray) return Array.isArray(val); |
|
return val instanceof Array; |
|
} |
|
|
|
function isError(val) { |
|
return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); |
|
} |
|
|
|
function isDate(val) { |
|
if (val instanceof Date) return true; |
|
return typeof val.toDateString === 'function' |
|
&& typeof val.getDate === 'function' |
|
&& typeof val.setDate === 'function'; |
|
} |
|
|
|
function isRegexp(val) { |
|
if (val instanceof RegExp) return true; |
|
return typeof val.flags === 'string' |
|
&& typeof val.ignoreCase === 'boolean' |
|
&& typeof val.multiline === 'boolean' |
|
&& typeof val.global === 'boolean'; |
|
} |
|
|
|
function isGeneratorFn(name, val) { |
|
return ctorName(name) === 'GeneratorFunction'; |
|
} |
|
|
|
function isGeneratorObj(val) { |
|
return typeof val.throw === 'function' |
|
&& typeof val.return === 'function' |
|
&& typeof val.next === 'function'; |
|
} |
|
|
|
function isArguments(val) { |
|
try { |
|
if (typeof val.length === 'number' && typeof val.callee === 'function') { |
|
return true; |
|
} |
|
} catch (err) { |
|
if (err.message.indexOf('callee') !== -1) { |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
/** |
|
* 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) { |
|
if (val.constructor && typeof val.constructor.isBuffer === 'function') { |
|
return val.constructor.isBuffer(val); |
|
} |
|
return false; |
|
}
|
|
|