index.js 9.8 KB

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