UNPKG

10.1 kBJavaScriptView Raw
1/**
2 * lodash 4.0.1 (Custom Build) <https://lodash.com/>
3 * Build: `lodash modularize exports="npm" -o ./`
4 * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
5 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
7 * Available under MIT license <https://lodash.com/license>
8 */
9var keysIn = require('lodash.keysin'),
10 rest = require('lodash.rest');
11
12/** Used as references for various `Number` constants. */
13var MAX_SAFE_INTEGER = 9007199254740991;
14
15/** `Object#toString` result references. */
16var funcTag = '[object Function]',
17 genTag = '[object GeneratorFunction]';
18
19/** Used to detect unsigned integer values. */
20var reIsUint = /^(?:0|[1-9]\d*)$/;
21
22/**
23 * Checks if `value` is a valid array-like index.
24 *
25 * @private
26 * @param {*} value The value to check.
27 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
28 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
29 */
30function isIndex(value, length) {
31 value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
32 length = length == null ? MAX_SAFE_INTEGER : length;
33 return value > -1 && value % 1 == 0 && value < length;
34}
35
36/** Used for built-in method references. */
37var objectProto = global.Object.prototype;
38
39/** Used to check objects for own properties. */
40var hasOwnProperty = objectProto.hasOwnProperty;
41
42/**
43 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
44 * of values.
45 */
46var objectToString = objectProto.toString;
47
48/**
49 * Assigns `value` to `key` of `object` if the existing value is not equivalent
50 * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
51 * for equality comparisons.
52 *
53 * @private
54 * @param {Object} object The object to modify.
55 * @param {string} key The key of the property to assign.
56 * @param {*} value The value to assign.
57 */
58function assignValue(object, key, value) {
59 var objValue = object[key];
60 if ((!eq(objValue, value) ||
61 (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) ||
62 (value === undefined && !(key in object))) {
63 object[key] = value;
64 }
65}
66
67/**
68 * The base implementation of `_.property` without support for deep paths.
69 *
70 * @private
71 * @param {string} key The key of the property to get.
72 * @returns {Function} Returns the new function.
73 */
74function baseProperty(key) {
75 return function(object) {
76 return object == null ? undefined : object[key];
77 };
78}
79
80/**
81 * Copies properties of `source` to `object`.
82 *
83 * @private
84 * @param {Object} source The object to copy properties from.
85 * @param {Array} props The property names to copy.
86 * @param {Object} [object={}] The object to copy properties to.
87 * @returns {Object} Returns `object`.
88 */
89function copyObject(source, props, object) {
90 return copyObjectWith(source, props, object);
91}
92
93/**
94 * This function is like `copyObject` except that it accepts a function to
95 * customize copied values.
96 *
97 * @private
98 * @param {Object} source The object to copy properties from.
99 * @param {Array} props The property names to copy.
100 * @param {Object} [object={}] The object to copy properties to.
101 * @param {Function} [customizer] The function to customize copied values.
102 * @returns {Object} Returns `object`.
103 */
104function copyObjectWith(source, props, object, customizer) {
105 object || (object = {});
106
107 var index = -1,
108 length = props.length;
109
110 while (++index < length) {
111 var key = props[index],
112 newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key];
113
114 assignValue(object, key, newValue);
115 }
116 return object;
117}
118
119/**
120 * Creates a function like `_.assign`.
121 *
122 * @private
123 * @param {Function} assigner The function to assign values.
124 * @returns {Function} Returns the new assigner function.
125 */
126function createAssigner(assigner) {
127 return rest(function(object, sources) {
128 var index = -1,
129 length = sources.length,
130 customizer = length > 1 ? sources[length - 1] : undefined,
131 guard = length > 2 ? sources[2] : undefined;
132
133 customizer = typeof customizer == 'function' ? (length--, customizer) : undefined;
134 if (guard && isIterateeCall(sources[0], sources[1], guard)) {
135 customizer = length < 3 ? undefined : customizer;
136 length = 1;
137 }
138 object = Object(object);
139 while (++index < length) {
140 var source = sources[index];
141 if (source) {
142 assigner(object, source, index, customizer);
143 }
144 }
145 return object;
146 });
147}
148
149/**
150 * Gets the "length" property value of `object`.
151 *
152 * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
153 * that affects Safari on at least iOS 8.1-8.3 ARM64.
154 *
155 * @private
156 * @param {Object} object The object to query.
157 * @returns {*} Returns the "length" value.
158 */
159var getLength = baseProperty('length');
160
161/**
162 * Checks if the provided arguments are from an iteratee call.
163 *
164 * @private
165 * @param {*} value The potential iteratee value argument.
166 * @param {*} index The potential iteratee index or key argument.
167 * @param {*} object The potential iteratee object argument.
168 * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
169 */
170function isIterateeCall(value, index, object) {
171 if (!isObject(object)) {
172 return false;
173 }
174 var type = typeof index;
175 if (type == 'number'
176 ? (isArrayLike(object) && isIndex(index, object.length))
177 : (type == 'string' && index in object)) {
178 return eq(object[index], value);
179 }
180 return false;
181}
182
183/**
184 * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
185 * comparison between two values to determine if they are equivalent.
186 *
187 * @static
188 * @memberOf _
189 * @category Lang
190 * @param {*} value The value to compare.
191 * @param {*} other The other value to compare.
192 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
193 * @example
194 *
195 * var object = { 'user': 'fred' };
196 * var other = { 'user': 'fred' };
197 *
198 * _.eq(object, object);
199 * // => true
200 *
201 * _.eq(object, other);
202 * // => false
203 *
204 * _.eq('a', 'a');
205 * // => true
206 *
207 * _.eq('a', Object('a'));
208 * // => false
209 *
210 * _.eq(NaN, NaN);
211 * // => true
212 */
213function eq(value, other) {
214 return value === other || (value !== value && other !== other);
215}
216
217/**
218 * Checks if `value` is array-like. A value is considered array-like if it's
219 * not a function and has a `value.length` that's an integer greater than or
220 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
221 *
222 * @static
223 * @memberOf _
224 * @type Function
225 * @category Lang
226 * @param {*} value The value to check.
227 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
228 * @example
229 *
230 * _.isArrayLike([1, 2, 3]);
231 * // => true
232 *
233 * _.isArrayLike(document.body.children);
234 * // => true
235 *
236 * _.isArrayLike('abc');
237 * // => true
238 *
239 * _.isArrayLike(_.noop);
240 * // => false
241 */
242function isArrayLike(value) {
243 return value != null &&
244 !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
245}
246
247/**
248 * Checks if `value` is classified as a `Function` object.
249 *
250 * @static
251 * @memberOf _
252 * @category Lang
253 * @param {*} value The value to check.
254 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
255 * @example
256 *
257 * _.isFunction(_);
258 * // => true
259 *
260 * _.isFunction(/abc/);
261 * // => false
262 */
263function isFunction(value) {
264 // The use of `Object#toString` avoids issues with the `typeof` operator
265 // in Safari 8 which returns 'object' for typed array constructors, and
266 // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
267 var tag = isObject(value) ? objectToString.call(value) : '';
268 return tag == funcTag || tag == genTag;
269}
270
271/**
272 * Checks if `value` is a valid array-like length.
273 *
274 * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
275 *
276 * @static
277 * @memberOf _
278 * @category Lang
279 * @param {*} value The value to check.
280 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
281 * @example
282 *
283 * _.isLength(3);
284 * // => true
285 *
286 * _.isLength(Number.MIN_VALUE);
287 * // => false
288 *
289 * _.isLength(Infinity);
290 * // => false
291 *
292 * _.isLength('3');
293 * // => false
294 */
295function isLength(value) {
296 return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
297}
298
299/**
300 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
301 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
302 *
303 * @static
304 * @memberOf _
305 * @category Lang
306 * @param {*} value The value to check.
307 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
308 * @example
309 *
310 * _.isObject({});
311 * // => true
312 *
313 * _.isObject([1, 2, 3]);
314 * // => true
315 *
316 * _.isObject(_.noop);
317 * // => true
318 *
319 * _.isObject(null);
320 * // => false
321 */
322function isObject(value) {
323 // Avoid a V8 JIT bug in Chrome 19-20.
324 // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
325 var type = typeof value;
326 return !!value && (type == 'object' || type == 'function');
327}
328
329/**
330 * This method is like `_.assign` except that it iterates over own and
331 * inherited source properties.
332 *
333 * **Note:** This method mutates `object`.
334 *
335 * @static
336 * @memberOf _
337 * @alias extend
338 * @category Object
339 * @param {Object} object The destination object.
340 * @param {...Object} [sources] The source objects.
341 * @returns {Object} Returns `object`.
342 * @example
343 *
344 * function Foo() {
345 * this.b = 2;
346 * }
347 *
348 * function Bar() {
349 * this.d = 4;
350 * }
351 *
352 * Foo.prototype.c = 3;
353 * Bar.prototype.e = 5;
354 *
355 * _.assignIn({ 'a': 1 }, new Foo, new Bar);
356 * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
357 */
358var assignIn = createAssigner(function(object, source) {
359 copyObject(source, keysIn(source), object);
360});
361
362module.exports = assignIn;