/** Used as references for various `Number` constants. */
const MAX_SAFE_INTEGER = 9007199254740991
/**
* Used to match `RegExp`
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
*/
const reRegExpChar = /[\\^$.*+?()[\]{}|]/g
/** Used to detect if a method is native. */
const reIsNative = RegExp(
`^${Function.prototype.toString
.call(Object.prototype.hasOwnProperty)
.replace(reRegExpChar, '\\$&')
.replace(
/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,
'$1.*?'
)}$`
)
/**
* 类型验证工具
* @classdesc 类型验证工具
* @class CheckUtil
* @link https://www.lodashjs.com/docs/lodash.isArrayLike
*/
class CheckUtil {
/**
* Gets the `toStringTag` of `value`.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
static getTag(value) {
if (value === null) {
return value === undefined ? '[object Undefined]' : '[object Null]'
}
return Object.prototype.toString.call(value)
}
/**
* Checks if `value` is classified as a boolean primitive or object.
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
* @example
*
* isBoolean(false)
* // => true
*
* isBoolean(null)
* // => false
*/
static isBoolean(value) {
return (
value === true ||
value === false ||
(CheckUtil.isObjectLike(value) &&
CheckUtil.getTag(value) === '[object Boolean]')
)
}
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* isObject({})
* // => true
*
* isObject([1, 2, 3])
* // => true
*
* isObject(Function)
* // => true
*
* isObject(null)
* // => false
*/
static isObject(value) {
const type = typeof value
return value !== null && (type === 'object' || type === 'function')
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* isObjectLike({})
* // => true
*
* isObjectLike([1, 2, 3])
* // => true
*
* isObjectLike(Function)
* // => false
*
* isObjectLike(null)
* // => false
*/
static isObjectLike(value) {
return typeof value === 'object' && value !== null
}
/**
* Checks if `value` is classified as a `Function` object.
*
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
* @example
*
* isFunction(class Any{})
* // => true
*
* isFunction(() => {})
* // => true
*
* isFunction(async () => {})
* // => true
*
* isFunction(function * Any() {})
* // => true
*
* isFunction(Math.round)
* // => true
*
* isFunction(/abc/)
* // => false
*/
static isFunction(value) {
return typeof value === 'function'
}
/**
* Checks if `value` is a valid array-like length.
*
* **Note:** This method is loosely based on
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
*
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
* @example
*
* isLength(3)
* // => true
*
* isLength(Number.MIN_VALUE)
* // => false
*
* isLength(Infinity)
* // => false
*
* isLength('3')
* // => false
*/
static isLength(value) {
return (
typeof value === 'number' &&
value > -1 &&
value % 1 === 0 &&
value <= MAX_SAFE_INTEGER
)
}
/**
* Checks if `value` is classified as a `String` primitive or object.
*
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a string, else `false`.
* @example
*
* isString('abc')
* // => true
*
* isString(1)
* // => false
*/
static isString(value) {
const type = typeof value
return (
type === 'string' ||
(type === 'object' &&
value !== null &&
!Array.isArray(value) &&
CheckUtil.getTag(value) === '[object String]')
)
}
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* isSymbol(Symbol.iterator)
* // => true
*
* isSymbol('abc')
* // => false
*/
static isSymbol(value) {
const type = typeof value
return (
type === 'symbol' ||
(type === 'object' &&
value !== null &&
CheckUtil.getTag(value) === '[object Symbol]')
)
}
/**
* Checks if `value` is `undefined`.
*
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
* @example
*
* isUndefined(void 0)
* // => true
*
* isUndefined(null)
* // => false
*/
static isUndefined(value) {
return value === undefined
}
/**
* Checks if `value` is `null`.
*
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is `null`, else `false`.
* @example
*
* isNull(null)
* // => true
*
* isNull(void 0)
* // => false
*/
static isNull(value) {
return value === null
}
/**
* Checks if `value` is `Array`.
*
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is `Array`, else `false`.
* @example
*
* isArray([1,2,3])
* // => true
*/
static isArray(value) {
return Array.isArray(value)
}
/**
* Checks if `value` is array-like. A value is considered array-like if it's
* not a function and has a `value.length` that's an integer greater than or
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
*
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
* @example
*
* isArrayLike([1, 2, 3])
* // => true
*
* isArrayLike(document.body.children)
* // => true
*
* isArrayLike('abc')
* // => true
*
* isArrayLike(Function)
* // => false
*/
static isArrayLike(value) {
return (
value !== null &&
typeof value !== 'function' &&
CheckUtil.isLength(value.length)
)
}
/**
* This method is like `isArrayLike` except that it also checks if `value`
* is an object.
*
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array-like object,
* else `false`.
* @example
*
* isArrayLikeObject([1, 2, 3])
* // => true
*
* isArrayLikeObject(document.body.children)
* // => true
*
* isArrayLikeObject('abc')
* // => false
*
* isArrayLikeObject(Function)
* // => false
*/
static isArrayLikeObject(value) {
return CheckUtil.isObjectLike(value) && CheckUtil.isArrayLike(value)
}
/**
* Checks if `value` is `null` or `undefined`.
*
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is nullish, else `false`.
* @example
*
* isNil(null)
* // => true
*
* isNil(void 0)
* // => true
*
* isNil(NaN)
* // => false
*/
static isNil(value) {
return value === null
}
/**
* Checks if `value` is classified as a `Number` primitive or object.
*
* **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
* classified as numbers, use the `Number.isFinite` method.
*
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a number, else `false`.
* @see isInteger, toInteger, toNumber
* @example
*
* isNumber(3)
* // => true
*
* isNumber(Number.MIN_VALUE)
* // => true
*
* isNumber(Infinity)
* // => true
*
* isNumber('3')
* // => false
*/
static isNumber(value) {
return (
typeof value === 'number' ||
(CheckUtil.isObjectLike(value) &&
CheckUtil.getTag(value) === '[object Number]')
)
}
/**
* Checks if `value` is a plain object, that is, an object created by the
* `Object` constructor or one with a `[[Prototype]]` of `null`.
*
* @since 0.8.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
* @example
*
* function Foo() {
* this.a = 1
* }
*
* isPlainObject(new Foo)
* // => false
*
* isPlainObject([1, 2, 3])
* // => false
*
* isPlainObject({ 'x': 0, 'y': 0 })
* // => true
*
* isPlainObject(Object.create(null))
* // => true
*/
static isPlainObject(value) {
if (
!CheckUtil.isObjectLike(value) ||
CheckUtil.getTag(value) !== '[object Object]'
) {
return false
}
if (Object.getPrototypeOf(value) === null) {
return true
}
let proto = value
while (Object.getPrototypeOf(proto) !== null) {
proto = Object.getPrototypeOf(proto)
}
return Object.getPrototypeOf(value) === proto
}
/**
* Checks if `value` is likely a DOM element.
*
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
* @example
*
* isElement(document.body)
* // => true
*
* isElement('<body>')
* // => false
*/
static isElement(value) {
return (
CheckUtil.isObjectLike(value) &&
value.nodeType === 1 &&
!CheckUtil.isPlainObject(value)
)
}
/**
* Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
* `SyntaxError`, `TypeError`, or `URIError` object.
*
* @since 3.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an error object, else `false`.
* @example
*
* isError(new Error)
* // => true
*
* isError(Error)
* // => false
*/
static isError(value) {
if (!CheckUtil.isObjectLike(value)) {
return false
}
const tag = CheckUtil.getTag(value)
return (
tag === '[object Error]' ||
tag === '[object DOMException]' ||
(typeof value.message === 'string' &&
typeof value.name === 'string' &&
!CheckUtil.isPlainObject(value))
)
}
/**
* Checks if `value` is likely an `arguments` object.
*
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an `arguments` object, else `false`.
* @example
*
* isArguments(function() { return arguments }())
* // => true
*
* isArguments([1, 2, 3])
* // => false
*/
static isArguments(value) {
return (
CheckUtil.isObjectLike(value) &&
CheckUtil.getTag(value) === '[object Arguments]'
)
}
/**
* Checks if `value` is a pristine native function.
*
* @since 3.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a native function,
* else `false`.
* @example
*
* isNative(Array.prototype.push)
* // => true
*
* isNative(isDate)
* // => false
*/
static isNative(value) {
return CheckUtil.isObject(value) && reIsNative.test(value)
}
}
export default CheckUtil