2 * lodash 3.1.2 (Custom Build) <https://lodash.com/>
3 * Build: `lodash modern modularize exports="npm" -o ./`
4 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
5 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
7 * Available under MIT license <https://lodash.com/license>
9 var getNative = require('lodash._getnative'),
10 isArguments = require('lodash.isarguments'),
11 isArray = require('lodash.isarray');
13 /** Used to detect unsigned integer values. */
14 var reIsUint = /^\d+$/;
16 /** Used for native method references. */
17 var objectProto = Object.prototype;
19 /** Used to check objects for own properties. */
20 var hasOwnProperty = objectProto.hasOwnProperty;
22 /* Native method references for those with the same name as other `lodash` methods. */
23 var nativeKeys = getNative(Object, 'keys');
26 * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
27 * of an array-like value.
29 var MAX_SAFE_INTEGER = 9007199254740991;
32 * The base implementation of `_.property` without support for deep paths.
35 * @param {string} key The key of the property to get.
36 * @returns {Function} Returns the new function.
38 function baseProperty(key) {
39 return function(object) {
40 return object == null ? undefined : object[key];
45 * Gets the "length" property value of `object`.
47 * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
48 * that affects Safari on at least iOS 8.1-8.3 ARM64.
51 * @param {Object} object The object to query.
52 * @returns {*} Returns the "length" value.
54 var getLength = baseProperty('length');
57 * Checks if `value` is array-like.
60 * @param {*} value The value to check.
61 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
63 function isArrayLike(value) {
64 return value != null && isLength(getLength(value));
68 * Checks if `value` is a valid array-like index.
71 * @param {*} value The value to check.
72 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
73 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
75 function isIndex(value, length) {
76 value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
77 length = length == null ? MAX_SAFE_INTEGER : length;
78 return value > -1 && value % 1 == 0 && value < length;
82 * Checks if `value` is a valid array-like length.
84 * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
87 * @param {*} value The value to check.
88 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
90 function isLength(value) {
91 return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
95 * A fallback implementation of `Object.keys` which creates an array of the
96 * own enumerable property names of `object`.
99 * @param {Object} object The object to query.
100 * @returns {Array} Returns the array of property names.
102 function shimKeys(object) {
103 var props = keysIn(object),
104 propsLength = props.length,
105 length = propsLength && object.length;
107 var allowIndexes = !!length && isLength(length) &&
108 (isArray(object) || isArguments(object));
113 while (++index < propsLength) {
114 var key = props[index];
115 if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
123 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
124 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
129 * @param {*} value The value to check.
130 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
136 * _.isObject([1, 2, 3]);
142 function isObject(value) {
143 // Avoid a V8 JIT bug in Chrome 19-20.
144 // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
145 var type = typeof value;
146 return !!value && (type == 'object' || type == 'function');
150 * Creates an array of the own enumerable property names of `object`.
152 * **Note:** Non-object values are coerced to objects. See the
153 * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
159 * @param {Object} object The object to query.
160 * @returns {Array} Returns the array of property names.
168 * Foo.prototype.c = 3;
171 * // => ['a', 'b'] (iteration order is not guaranteed)
176 var keys = !nativeKeys ? shimKeys : function(object) {
177 var Ctor = object == null ? undefined : object.constructor;
178 if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
179 (typeof object != 'function' && isArrayLike(object))) {
180 return shimKeys(object);
182 return isObject(object) ? nativeKeys(object) : [];
186 * Creates an array of the own and inherited enumerable property names of `object`.
188 * **Note:** Non-object values are coerced to objects.
193 * @param {Object} object The object to query.
194 * @returns {Array} Returns the array of property names.
202 * Foo.prototype.c = 3;
205 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
207 function keysIn(object) {
208 if (object == null) {
211 if (!isObject(object)) {
212 object = Object(object);
214 var length = object.length;
215 length = (length && isLength(length) &&
216 (isArray(object) || isArguments(object)) && length) || 0;
218 var Ctor = object.constructor,
220 isProto = typeof Ctor == 'function' && Ctor.prototype === object,
221 result = Array(length),
222 skipIndexes = length > 0;
224 while (++index < length) {
225 result[index] = (index + '');
227 for (var key in object) {
228 if (!(skipIndexes && isIndex(key, length)) &&
229 !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
236 module.exports = keys;