index.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /**
  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
  8. */
  9. /** Used as references for various `Number` constants. */
  10. var MAX_SAFE_INTEGER = 9007199254740991;
  11. /** `Object#toString` result references. */
  12. var argsTag = '[object Arguments]',
  13. funcTag = '[object Function]',
  14. genTag = '[object GeneratorFunction]';
  15. /** Used to detect unsigned integer values. */
  16. var reIsUint = /^(?:0|[1-9]\d*)$/;
  17. /**
  18. * The base implementation of `_.times` without support for iteratee shorthands
  19. * or max array length checks.
  20. *
  21. * @private
  22. * @param {number} n The number of times to invoke `iteratee`.
  23. * @param {Function} iteratee The function invoked per iteration.
  24. * @returns {Array} Returns the array of results.
  25. */
  26. function baseTimes(n, iteratee) {
  27. var index = -1,
  28. result = Array(n);
  29. while (++index < n) {
  30. result[index] = iteratee(index);
  31. }
  32. return result;
  33. }
  34. /**
  35. * Creates a unary function that invokes `func` with its argument transformed.
  36. *
  37. * @private
  38. * @param {Function} func The function to wrap.
  39. * @param {Function} transform The argument transform.
  40. * @returns {Function} Returns the new function.
  41. */
  42. function overArg(func, transform) {
  43. return function(arg) {
  44. return func(transform(arg));
  45. };
  46. }
  47. /** Used for built-in method references. */
  48. var objectProto = Object.prototype;
  49. /** Used to check objects for own properties. */
  50. var hasOwnProperty = objectProto.hasOwnProperty;
  51. /**
  52. * Used to resolve the
  53. * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  54. * of values.
  55. */
  56. var objectToString = objectProto.toString;
  57. /** Built-in value references. */
  58. var propertyIsEnumerable = objectProto.propertyIsEnumerable;
  59. /* Built-in method references for those with the same name as other `lodash` methods. */
  60. var nativeKeys = overArg(Object.keys, Object);
  61. /**
  62. * Creates an array of the enumerable property names of the array-like `value`.
  63. *
  64. * @private
  65. * @param {*} value The value to query.
  66. * @param {boolean} inherited Specify returning inherited property names.
  67. * @returns {Array} Returns the array of property names.
  68. */
  69. function arrayLikeKeys(value, inherited) {
  70. // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
  71. // Safari 9 makes `arguments.length` enumerable in strict mode.
  72. var result = (isArray(value) || isArguments(value))
  73. ? baseTimes(value.length, String)
  74. : [];
  75. var length = result.length,
  76. skipIndexes = !!length;
  77. for (var key in value) {
  78. if ((inherited || hasOwnProperty.call(value, key)) &&
  79. !(skipIndexes && (key == 'length' || isIndex(key, length)))) {
  80. result.push(key);
  81. }
  82. }
  83. return result;
  84. }
  85. /**
  86. * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
  87. *
  88. * @private
  89. * @param {Object} object The object to query.
  90. * @returns {Array} Returns the array of property names.
  91. */
  92. function baseKeys(object) {
  93. if (!isPrototype(object)) {
  94. return nativeKeys(object);
  95. }
  96. var result = [];
  97. for (var key in Object(object)) {
  98. if (hasOwnProperty.call(object, key) && key != 'constructor') {
  99. result.push(key);
  100. }
  101. }
  102. return result;
  103. }
  104. /**
  105. * Checks if `value` is a valid array-like index.
  106. *
  107. * @private
  108. * @param {*} value The value to check.
  109. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
  110. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
  111. */
  112. function isIndex(value, length) {
  113. length = length == null ? MAX_SAFE_INTEGER : length;
  114. return !!length &&
  115. (typeof value == 'number' || reIsUint.test(value)) &&
  116. (value > -1 && value % 1 == 0 && value < length);
  117. }
  118. /**
  119. * Checks if `value` is likely a prototype object.
  120. *
  121. * @private
  122. * @param {*} value The value to check.
  123. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
  124. */
  125. function isPrototype(value) {
  126. var Ctor = value && value.constructor,
  127. proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
  128. return value === proto;
  129. }
  130. /**
  131. * Checks if `value` is likely an `arguments` object.
  132. *
  133. * @static
  134. * @memberOf _
  135. * @since 0.1.0
  136. * @category Lang
  137. * @param {*} value The value to check.
  138. * @returns {boolean} Returns `true` if `value` is an `arguments` object,
  139. * else `false`.
  140. * @example
  141. *
  142. * _.isArguments(function() { return arguments; }());
  143. * // => true
  144. *
  145. * _.isArguments([1, 2, 3]);
  146. * // => false
  147. */
  148. function isArguments(value) {
  149. // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
  150. return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
  151. (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
  152. }
  153. /**
  154. * Checks if `value` is classified as an `Array` object.
  155. *
  156. * @static
  157. * @memberOf _
  158. * @since 0.1.0
  159. * @category Lang
  160. * @param {*} value The value to check.
  161. * @returns {boolean} Returns `true` if `value` is an array, else `false`.
  162. * @example
  163. *
  164. * _.isArray([1, 2, 3]);
  165. * // => true
  166. *
  167. * _.isArray(document.body.children);
  168. * // => false
  169. *
  170. * _.isArray('abc');
  171. * // => false
  172. *
  173. * _.isArray(_.noop);
  174. * // => false
  175. */
  176. var isArray = Array.isArray;
  177. /**
  178. * Checks if `value` is array-like. A value is considered array-like if it's
  179. * not a function and has a `value.length` that's an integer greater than or
  180. * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
  181. *
  182. * @static
  183. * @memberOf _
  184. * @since 4.0.0
  185. * @category Lang
  186. * @param {*} value The value to check.
  187. * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
  188. * @example
  189. *
  190. * _.isArrayLike([1, 2, 3]);
  191. * // => true
  192. *
  193. * _.isArrayLike(document.body.children);
  194. * // => true
  195. *
  196. * _.isArrayLike('abc');
  197. * // => true
  198. *
  199. * _.isArrayLike(_.noop);
  200. * // => false
  201. */
  202. function isArrayLike(value) {
  203. return value != null && isLength(value.length) && !isFunction(value);
  204. }
  205. /**
  206. * This method is like `_.isArrayLike` except that it also checks if `value`
  207. * is an object.
  208. *
  209. * @static
  210. * @memberOf _
  211. * @since 4.0.0
  212. * @category Lang
  213. * @param {*} value The value to check.
  214. * @returns {boolean} Returns `true` if `value` is an array-like object,
  215. * else `false`.
  216. * @example
  217. *
  218. * _.isArrayLikeObject([1, 2, 3]);
  219. * // => true
  220. *
  221. * _.isArrayLikeObject(document.body.children);
  222. * // => true
  223. *
  224. * _.isArrayLikeObject('abc');
  225. * // => false
  226. *
  227. * _.isArrayLikeObject(_.noop);
  228. * // => false
  229. */
  230. function isArrayLikeObject(value) {
  231. return isObjectLike(value) && isArrayLike(value);
  232. }
  233. /**
  234. * Checks if `value` is classified as a `Function` object.
  235. *
  236. * @static
  237. * @memberOf _
  238. * @since 0.1.0
  239. * @category Lang
  240. * @param {*} value The value to check.
  241. * @returns {boolean} Returns `true` if `value` is a function, else `false`.
  242. * @example
  243. *
  244. * _.isFunction(_);
  245. * // => true
  246. *
  247. * _.isFunction(/abc/);
  248. * // => false
  249. */
  250. function isFunction(value) {
  251. // The use of `Object#toString` avoids issues with the `typeof` operator
  252. // in Safari 8-9 which returns 'object' for typed array and other constructors.
  253. var tag = isObject(value) ? objectToString.call(value) : '';
  254. return tag == funcTag || tag == genTag;
  255. }
  256. /**
  257. * Checks if `value` is a valid array-like length.
  258. *
  259. * **Note:** This method is loosely based on
  260. * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
  261. *
  262. * @static
  263. * @memberOf _
  264. * @since 4.0.0
  265. * @category Lang
  266. * @param {*} value The value to check.
  267. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
  268. * @example
  269. *
  270. * _.isLength(3);
  271. * // => true
  272. *
  273. * _.isLength(Number.MIN_VALUE);
  274. * // => false
  275. *
  276. * _.isLength(Infinity);
  277. * // => false
  278. *
  279. * _.isLength('3');
  280. * // => false
  281. */
  282. function isLength(value) {
  283. return typeof value == 'number' &&
  284. value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
  285. }
  286. /**
  287. * Checks if `value` is the
  288. * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
  289. * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  290. *
  291. * @static
  292. * @memberOf _
  293. * @since 0.1.0
  294. * @category Lang
  295. * @param {*} value The value to check.
  296. * @returns {boolean} Returns `true` if `value` is an object, else `false`.
  297. * @example
  298. *
  299. * _.isObject({});
  300. * // => true
  301. *
  302. * _.isObject([1, 2, 3]);
  303. * // => true
  304. *
  305. * _.isObject(_.noop);
  306. * // => true
  307. *
  308. * _.isObject(null);
  309. * // => false
  310. */
  311. function isObject(value) {
  312. var type = typeof value;
  313. return !!value && (type == 'object' || type == 'function');
  314. }
  315. /**
  316. * Checks if `value` is object-like. A value is object-like if it's not `null`
  317. * and has a `typeof` result of "object".
  318. *
  319. * @static
  320. * @memberOf _
  321. * @since 4.0.0
  322. * @category Lang
  323. * @param {*} value The value to check.
  324. * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
  325. * @example
  326. *
  327. * _.isObjectLike({});
  328. * // => true
  329. *
  330. * _.isObjectLike([1, 2, 3]);
  331. * // => true
  332. *
  333. * _.isObjectLike(_.noop);
  334. * // => false
  335. *
  336. * _.isObjectLike(null);
  337. * // => false
  338. */
  339. function isObjectLike(value) {
  340. return !!value && typeof value == 'object';
  341. }
  342. /**
  343. * Creates an array of the own enumerable property names of `object`.
  344. *
  345. * **Note:** Non-object values are coerced to objects. See the
  346. * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
  347. * for more details.
  348. *
  349. * @static
  350. * @since 0.1.0
  351. * @memberOf _
  352. * @category Object
  353. * @param {Object} object The object to query.
  354. * @returns {Array} Returns the array of property names.
  355. * @example
  356. *
  357. * function Foo() {
  358. * this.a = 1;
  359. * this.b = 2;
  360. * }
  361. *
  362. * Foo.prototype.c = 3;
  363. *
  364. * _.keys(new Foo);
  365. * // => ['a', 'b'] (iteration order is not guaranteed)
  366. *
  367. * _.keys('hi');
  368. * // => ['0', '1']
  369. */
  370. function keys(object) {
  371. return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
  372. }
  373. module.exports = keys;