2 * lodash (Custom Build) <https://lodash.com/>
3 * Build: `lodash modularize exports="npm" -o ./`
4 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
5 * Released under MIT license <https://lodash.com/license>
6 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
10 /** Used as references for various `Number` constants. */
11 var MAX_SAFE_INTEGER = 9007199254740991;
13 /** `Object#toString` result references. */
14 var argsTag = '[object Arguments]',
15 funcTag = '[object Function]',
16 genTag = '[object GeneratorFunction]',
17 mapTag = '[object Map]',
18 objectTag = '[object Object]',
19 promiseTag = '[object Promise]',
20 setTag = '[object Set]',
21 weakMapTag = '[object WeakMap]';
23 var dataViewTag = '[object DataView]';
26 * Used to match `RegExp`
27 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
29 var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
31 /** Used to detect host constructors (Safari). */
32 var reIsHostCtor = /^\[object .+?Constructor\]$/;
34 /** Detect free variable `global` from Node.js. */
35 var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
37 /** Detect free variable `self`. */
38 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
40 /** Used as a reference to the global object. */
41 var root = freeGlobal || freeSelf || Function('return this')();
43 /** Detect free variable `exports`. */
44 var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
46 /** Detect free variable `module`. */
47 var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
49 /** Detect the popular CommonJS extension `module.exports`. */
50 var moduleExports = freeModule && freeModule.exports === freeExports;
53 * Gets the value at `key` of `object`.
56 * @param {Object} [object] The object to query.
57 * @param {string} key The key of the property to get.
58 * @returns {*} Returns the property value.
60 function getValue(object, key) {
61 return object == null ? undefined : object[key];
65 * Checks if `value` is a host object in IE < 9.
68 * @param {*} value The value to check.
69 * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
71 function isHostObject(value) {
72 // Many host objects are `Object` objects that can coerce to strings
73 // despite having improperly defined `toString` methods.
75 if (value != null && typeof value.toString != 'function') {
77 result = !!(value + '');
84 * Creates a unary function that invokes `func` with its argument transformed.
87 * @param {Function} func The function to wrap.
88 * @param {Function} transform The argument transform.
89 * @returns {Function} Returns the new function.
91 function overArg(func, transform) {
92 return function(arg) {
93 return func(transform(arg));
97 /** Used for built-in method references. */
98 var funcProto = Function.prototype,
99 objectProto = Object.prototype;
101 /** Used to detect overreaching core-js shims. */
102 var coreJsData = root['__core-js_shared__'];
104 /** Used to detect methods masquerading as native. */
105 var maskSrcKey = (function() {
106 var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
107 return uid ? ('Symbol(src)_1.' + uid) : '';
110 /** Used to resolve the decompiled source of functions. */
111 var funcToString = funcProto.toString;
113 /** Used to check objects for own properties. */
114 var hasOwnProperty = objectProto.hasOwnProperty;
117 * Used to resolve the
118 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
121 var objectToString = objectProto.toString;
123 /** Used to detect if a method is native. */
124 var reIsNative = RegExp('^' +
125 funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
126 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
129 /** Built-in value references. */
130 var Buffer = moduleExports ? root.Buffer : undefined,
131 propertyIsEnumerable = objectProto.propertyIsEnumerable;
133 /* Built-in method references for those with the same name as other `lodash` methods. */
134 var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
135 nativeKeys = overArg(Object.keys, Object);
137 /* Built-in method references that are verified to be native. */
138 var DataView = getNative(root, 'DataView'),
139 Map = getNative(root, 'Map'),
140 Promise = getNative(root, 'Promise'),
141 Set = getNative(root, 'Set'),
142 WeakMap = getNative(root, 'WeakMap');
144 /** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */
145 var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');
147 /** Used to detect maps, sets, and weakmaps. */
148 var dataViewCtorString = toSource(DataView),
149 mapCtorString = toSource(Map),
150 promiseCtorString = toSource(Promise),
151 setCtorString = toSource(Set),
152 weakMapCtorString = toSource(WeakMap);
155 * The base implementation of `getTag`.
158 * @param {*} value The value to query.
159 * @returns {string} Returns the `toStringTag`.
161 function baseGetTag(value) {
162 return objectToString.call(value);
166 * The base implementation of `_.isNative` without bad shim checks.
169 * @param {*} value The value to check.
170 * @returns {boolean} Returns `true` if `value` is a native function,
173 function baseIsNative(value) {
174 if (!isObject(value) || isMasked(value)) {
177 var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
178 return pattern.test(toSource(value));
182 * Gets the native function at `key` of `object`.
185 * @param {Object} object The object to query.
186 * @param {string} key The key of the method to get.
187 * @returns {*} Returns the function if it's native, else `undefined`.
189 function getNative(object, key) {
190 var value = getValue(object, key);
191 return baseIsNative(value) ? value : undefined;
195 * Gets the `toStringTag` of `value`.
198 * @param {*} value The value to query.
199 * @returns {string} Returns the `toStringTag`.
201 var getTag = baseGetTag;
203 // Fallback for data views, maps, sets, and weak maps in IE 11,
204 // for data views in Edge < 14, and promises in Node.js.
205 if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
206 (Map && getTag(new Map) != mapTag) ||
207 (Promise && getTag(Promise.resolve()) != promiseTag) ||
208 (Set && getTag(new Set) != setTag) ||
209 (WeakMap && getTag(new WeakMap) != weakMapTag)) {
210 getTag = function(value) {
211 var result = objectToString.call(value),
212 Ctor = result == objectTag ? value.constructor : undefined,
213 ctorString = Ctor ? toSource(Ctor) : undefined;
216 switch (ctorString) {
217 case dataViewCtorString: return dataViewTag;
218 case mapCtorString: return mapTag;
219 case promiseCtorString: return promiseTag;
220 case setCtorString: return setTag;
221 case weakMapCtorString: return weakMapTag;
229 * Checks if `func` has its source masked.
232 * @param {Function} func The function to check.
233 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
235 function isMasked(func) {
236 return !!maskSrcKey && (maskSrcKey in func);
240 * Checks if `value` is likely a prototype object.
243 * @param {*} value The value to check.
244 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
246 function isPrototype(value) {
247 var Ctor = value && value.constructor,
248 proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
250 return value === proto;
254 * Converts `func` to its source code.
257 * @param {Function} func The function to process.
258 * @returns {string} Returns the source code.
260 function toSource(func) {
263 return funcToString.call(func);
273 * Checks if `value` is likely an `arguments` object.
279 * @param {*} value The value to check.
280 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
284 * _.isArguments(function() { return arguments; }());
287 * _.isArguments([1, 2, 3]);
290 function isArguments(value) {
291 // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
292 return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
293 (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
297 * Checks if `value` is classified as an `Array` object.
303 * @param {*} value The value to check.
304 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
307 * _.isArray([1, 2, 3]);
310 * _.isArray(document.body.children);
319 var isArray = Array.isArray;
322 * Checks if `value` is array-like. A value is considered array-like if it's
323 * not a function and has a `value.length` that's an integer greater than or
324 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
330 * @param {*} value The value to check.
331 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
334 * _.isArrayLike([1, 2, 3]);
337 * _.isArrayLike(document.body.children);
340 * _.isArrayLike('abc');
343 * _.isArrayLike(_.noop);
346 function isArrayLike(value) {
347 return value != null && isLength(value.length) && !isFunction(value);
351 * This method is like `_.isArrayLike` except that it also checks if `value`
358 * @param {*} value The value to check.
359 * @returns {boolean} Returns `true` if `value` is an array-like object,
363 * _.isArrayLikeObject([1, 2, 3]);
366 * _.isArrayLikeObject(document.body.children);
369 * _.isArrayLikeObject('abc');
372 * _.isArrayLikeObject(_.noop);
375 function isArrayLikeObject(value) {
376 return isObjectLike(value) && isArrayLike(value);
380 * Checks if `value` is a buffer.
386 * @param {*} value The value to check.
387 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
390 * _.isBuffer(new Buffer(2));
393 * _.isBuffer(new Uint8Array(2));
396 var isBuffer = nativeIsBuffer || stubFalse;
399 * Checks if `value` is an empty object, collection, map, or set.
401 * Objects are considered empty if they have no own enumerable string keyed
404 * Array-like values such as `arguments` objects, arrays, buffers, strings, or
405 * jQuery-like collections are considered empty if they have a `length` of `0`.
406 * Similarly, maps and sets are considered empty if they have a `size` of `0`.
412 * @param {*} value The value to check.
413 * @returns {boolean} Returns `true` if `value` is empty, else `false`.
425 * _.isEmpty([1, 2, 3]);
428 * _.isEmpty({ 'a': 1 });
431 function isEmpty(value) {
432 if (isArrayLike(value) &&
433 (isArray(value) || typeof value == 'string' ||
434 typeof value.splice == 'function' || isBuffer(value) || isArguments(value))) {
435 return !value.length;
437 var tag = getTag(value);
438 if (tag == mapTag || tag == setTag) {
441 if (nonEnumShadows || isPrototype(value)) {
442 return !nativeKeys(value).length;
444 for (var key in value) {
445 if (hasOwnProperty.call(value, key)) {
453 * Checks if `value` is classified as a `Function` object.
459 * @param {*} value The value to check.
460 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
466 * _.isFunction(/abc/);
469 function isFunction(value) {
470 // The use of `Object#toString` avoids issues with the `typeof` operator
471 // in Safari 8-9 which returns 'object' for typed array and other constructors.
472 var tag = isObject(value) ? objectToString.call(value) : '';
473 return tag == funcTag || tag == genTag;
477 * Checks if `value` is a valid array-like length.
479 * **Note:** This method is loosely based on
480 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
486 * @param {*} value The value to check.
487 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
493 * _.isLength(Number.MIN_VALUE);
496 * _.isLength(Infinity);
502 function isLength(value) {
503 return typeof value == 'number' &&
504 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
508 * Checks if `value` is the
509 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
510 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
516 * @param {*} value The value to check.
517 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
523 * _.isObject([1, 2, 3]);
526 * _.isObject(_.noop);
532 function isObject(value) {
533 var type = typeof value;
534 return !!value && (type == 'object' || type == 'function');
538 * Checks if `value` is object-like. A value is object-like if it's not `null`
539 * and has a `typeof` result of "object".
545 * @param {*} value The value to check.
546 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
549 * _.isObjectLike({});
552 * _.isObjectLike([1, 2, 3]);
555 * _.isObjectLike(_.noop);
558 * _.isObjectLike(null);
561 function isObjectLike(value) {
562 return !!value && typeof value == 'object';
566 * This method returns `false`.
572 * @returns {boolean} Returns `false`.
575 * _.times(2, _.stubFalse);
576 * // => [false, false]
578 function stubFalse() {
582 module.exports = isEmpty;