Initial commit
[yaffs-website] / node_modules / lodash.keys / index.js
1 /**
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>
8  */
9 var getNative = require('lodash._getnative'),
10     isArguments = require('lodash.isarguments'),
11     isArray = require('lodash.isarray');
12
13 /** Used to detect unsigned integer values. */
14 var reIsUint = /^\d+$/;
15
16 /** Used for native method references. */
17 var objectProto = Object.prototype;
18
19 /** Used to check objects for own properties. */
20 var hasOwnProperty = objectProto.hasOwnProperty;
21
22 /* Native method references for those with the same name as other `lodash` methods. */
23 var nativeKeys = getNative(Object, 'keys');
24
25 /**
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.
28  */
29 var MAX_SAFE_INTEGER = 9007199254740991;
30
31 /**
32  * The base implementation of `_.property` without support for deep paths.
33  *
34  * @private
35  * @param {string} key The key of the property to get.
36  * @returns {Function} Returns the new function.
37  */
38 function baseProperty(key) {
39   return function(object) {
40     return object == null ? undefined : object[key];
41   };
42 }
43
44 /**
45  * Gets the "length" property value of `object`.
46  *
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.
49  *
50  * @private
51  * @param {Object} object The object to query.
52  * @returns {*} Returns the "length" value.
53  */
54 var getLength = baseProperty('length');
55
56 /**
57  * Checks if `value` is array-like.
58  *
59  * @private
60  * @param {*} value The value to check.
61  * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
62  */
63 function isArrayLike(value) {
64   return value != null && isLength(getLength(value));
65 }
66
67 /**
68  * Checks if `value` is a valid array-like index.
69  *
70  * @private
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`.
74  */
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;
79 }
80
81 /**
82  * Checks if `value` is a valid array-like length.
83  *
84  * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
85  *
86  * @private
87  * @param {*} value The value to check.
88  * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
89  */
90 function isLength(value) {
91   return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
92 }
93
94 /**
95  * A fallback implementation of `Object.keys` which creates an array of the
96  * own enumerable property names of `object`.
97  *
98  * @private
99  * @param {Object} object The object to query.
100  * @returns {Array} Returns the array of property names.
101  */
102 function shimKeys(object) {
103   var props = keysIn(object),
104       propsLength = props.length,
105       length = propsLength && object.length;
106
107   var allowIndexes = !!length && isLength(length) &&
108     (isArray(object) || isArguments(object));
109
110   var index = -1,
111       result = [];
112
113   while (++index < propsLength) {
114     var key = props[index];
115     if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
116       result.push(key);
117     }
118   }
119   return result;
120 }
121
122 /**
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('')`)
125  *
126  * @static
127  * @memberOf _
128  * @category Lang
129  * @param {*} value The value to check.
130  * @returns {boolean} Returns `true` if `value` is an object, else `false`.
131  * @example
132  *
133  * _.isObject({});
134  * // => true
135  *
136  * _.isObject([1, 2, 3]);
137  * // => true
138  *
139  * _.isObject(1);
140  * // => false
141  */
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');
147 }
148
149 /**
150  * Creates an array of the own enumerable property names of `object`.
151  *
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)
154  * for more details.
155  *
156  * @static
157  * @memberOf _
158  * @category Object
159  * @param {Object} object The object to query.
160  * @returns {Array} Returns the array of property names.
161  * @example
162  *
163  * function Foo() {
164  *   this.a = 1;
165  *   this.b = 2;
166  * }
167  *
168  * Foo.prototype.c = 3;
169  *
170  * _.keys(new Foo);
171  * // => ['a', 'b'] (iteration order is not guaranteed)
172  *
173  * _.keys('hi');
174  * // => ['0', '1']
175  */
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);
181   }
182   return isObject(object) ? nativeKeys(object) : [];
183 };
184
185 /**
186  * Creates an array of the own and inherited enumerable property names of `object`.
187  *
188  * **Note:** Non-object values are coerced to objects.
189  *
190  * @static
191  * @memberOf _
192  * @category Object
193  * @param {Object} object The object to query.
194  * @returns {Array} Returns the array of property names.
195  * @example
196  *
197  * function Foo() {
198  *   this.a = 1;
199  *   this.b = 2;
200  * }
201  *
202  * Foo.prototype.c = 3;
203  *
204  * _.keysIn(new Foo);
205  * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
206  */
207 function keysIn(object) {
208   if (object == null) {
209     return [];
210   }
211   if (!isObject(object)) {
212     object = Object(object);
213   }
214   var length = object.length;
215   length = (length && isLength(length) &&
216     (isArray(object) || isArguments(object)) && length) || 0;
217
218   var Ctor = object.constructor,
219       index = -1,
220       isProto = typeof Ctor == 'function' && Ctor.prototype === object,
221       result = Array(length),
222       skipIndexes = length > 0;
223
224   while (++index < length) {
225     result[index] = (index + '');
226   }
227   for (var key in object) {
228     if (!(skipIndexes && isIndex(key, length)) &&
229         !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
230       result.push(key);
231     }
232   }
233   return result;
234 }
235
236 module.exports = keys;