Initial commit
[yaffs-website] / node_modules / lodash.assignwith / index.js
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
10 /** Used as references for various `Number` constants. */
11 var MAX_SAFE_INTEGER = 9007199254740991;
12
13 /** `Object#toString` result references. */
14 var argsTag = '[object Arguments]',
15     funcTag = '[object Function]',
16     genTag = '[object GeneratorFunction]';
17
18 /** Used to detect unsigned integer values. */
19 var reIsUint = /^(?:0|[1-9]\d*)$/;
20
21 /**
22  * A faster alternative to `Function#apply`, this function invokes `func`
23  * with the `this` binding of `thisArg` and the arguments of `args`.
24  *
25  * @private
26  * @param {Function} func The function to invoke.
27  * @param {*} thisArg The `this` binding of `func`.
28  * @param {Array} args The arguments to invoke `func` with.
29  * @returns {*} Returns the result of `func`.
30  */
31 function apply(func, thisArg, args) {
32   switch (args.length) {
33     case 0: return func.call(thisArg);
34     case 1: return func.call(thisArg, args[0]);
35     case 2: return func.call(thisArg, args[0], args[1]);
36     case 3: return func.call(thisArg, args[0], args[1], args[2]);
37   }
38   return func.apply(thisArg, args);
39 }
40
41 /**
42  * The base implementation of `_.times` without support for iteratee shorthands
43  * or max array length checks.
44  *
45  * @private
46  * @param {number} n The number of times to invoke `iteratee`.
47  * @param {Function} iteratee The function invoked per iteration.
48  * @returns {Array} Returns the array of results.
49  */
50 function baseTimes(n, iteratee) {
51   var index = -1,
52       result = Array(n);
53
54   while (++index < n) {
55     result[index] = iteratee(index);
56   }
57   return result;
58 }
59
60 /**
61  * Creates a unary function that invokes `func` with its argument transformed.
62  *
63  * @private
64  * @param {Function} func The function to wrap.
65  * @param {Function} transform The argument transform.
66  * @returns {Function} Returns the new function.
67  */
68 function overArg(func, transform) {
69   return function(arg) {
70     return func(transform(arg));
71   };
72 }
73
74 /** Used for built-in method references. */
75 var objectProto = Object.prototype;
76
77 /** Used to check objects for own properties. */
78 var hasOwnProperty = objectProto.hasOwnProperty;
79
80 /**
81  * Used to resolve the
82  * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
83  * of values.
84  */
85 var objectToString = objectProto.toString;
86
87 /** Built-in value references. */
88 var propertyIsEnumerable = objectProto.propertyIsEnumerable;
89
90 /* Built-in method references for those with the same name as other `lodash` methods. */
91 var nativeKeys = overArg(Object.keys, Object),
92     nativeMax = Math.max;
93
94 /**
95  * Creates an array of the enumerable property names of the array-like `value`.
96  *
97  * @private
98  * @param {*} value The value to query.
99  * @param {boolean} inherited Specify returning inherited property names.
100  * @returns {Array} Returns the array of property names.
101  */
102 function arrayLikeKeys(value, inherited) {
103   // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
104   // Safari 9 makes `arguments.length` enumerable in strict mode.
105   var result = (isArray(value) || isArguments(value))
106     ? baseTimes(value.length, String)
107     : [];
108
109   var length = result.length,
110       skipIndexes = !!length;
111
112   for (var key in value) {
113     if ((inherited || hasOwnProperty.call(value, key)) &&
114         !(skipIndexes && (key == 'length' || isIndex(key, length)))) {
115       result.push(key);
116     }
117   }
118   return result;
119 }
120
121 /**
122  * Assigns `value` to `key` of `object` if the existing value is not equivalent
123  * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
124  * for equality comparisons.
125  *
126  * @private
127  * @param {Object} object The object to modify.
128  * @param {string} key The key of the property to assign.
129  * @param {*} value The value to assign.
130  */
131 function assignValue(object, key, value) {
132   var objValue = object[key];
133   if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
134       (value === undefined && !(key in object))) {
135     object[key] = value;
136   }
137 }
138
139 /**
140  * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
141  *
142  * @private
143  * @param {Object} object The object to query.
144  * @returns {Array} Returns the array of property names.
145  */
146 function baseKeys(object) {
147   if (!isPrototype(object)) {
148     return nativeKeys(object);
149   }
150   var result = [];
151   for (var key in Object(object)) {
152     if (hasOwnProperty.call(object, key) && key != 'constructor') {
153       result.push(key);
154     }
155   }
156   return result;
157 }
158
159 /**
160  * The base implementation of `_.rest` which doesn't validate or coerce arguments.
161  *
162  * @private
163  * @param {Function} func The function to apply a rest parameter to.
164  * @param {number} [start=func.length-1] The start position of the rest parameter.
165  * @returns {Function} Returns the new function.
166  */
167 function baseRest(func, start) {
168   start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
169   return function() {
170     var args = arguments,
171         index = -1,
172         length = nativeMax(args.length - start, 0),
173         array = Array(length);
174
175     while (++index < length) {
176       array[index] = args[start + index];
177     }
178     index = -1;
179     var otherArgs = Array(start + 1);
180     while (++index < start) {
181       otherArgs[index] = args[index];
182     }
183     otherArgs[start] = array;
184     return apply(func, this, otherArgs);
185   };
186 }
187
188 /**
189  * Copies properties of `source` to `object`.
190  *
191  * @private
192  * @param {Object} source The object to copy properties from.
193  * @param {Array} props The property identifiers to copy.
194  * @param {Object} [object={}] The object to copy properties to.
195  * @param {Function} [customizer] The function to customize copied values.
196  * @returns {Object} Returns `object`.
197  */
198 function copyObject(source, props, object, customizer) {
199   object || (object = {});
200
201   var index = -1,
202       length = props.length;
203
204   while (++index < length) {
205     var key = props[index];
206
207     var newValue = customizer
208       ? customizer(object[key], source[key], key, object, source)
209       : undefined;
210
211     assignValue(object, key, newValue === undefined ? source[key] : newValue);
212   }
213   return object;
214 }
215
216 /**
217  * Creates a function like `_.assign`.
218  *
219  * @private
220  * @param {Function} assigner The function to assign values.
221  * @returns {Function} Returns the new assigner function.
222  */
223 function createAssigner(assigner) {
224   return baseRest(function(object, sources) {
225     var index = -1,
226         length = sources.length,
227         customizer = length > 1 ? sources[length - 1] : undefined,
228         guard = length > 2 ? sources[2] : undefined;
229
230     customizer = (assigner.length > 3 && typeof customizer == 'function')
231       ? (length--, customizer)
232       : undefined;
233
234     if (guard && isIterateeCall(sources[0], sources[1], guard)) {
235       customizer = length < 3 ? undefined : customizer;
236       length = 1;
237     }
238     object = Object(object);
239     while (++index < length) {
240       var source = sources[index];
241       if (source) {
242         assigner(object, source, index, customizer);
243       }
244     }
245     return object;
246   });
247 }
248
249 /**
250  * Checks if `value` is a valid array-like index.
251  *
252  * @private
253  * @param {*} value The value to check.
254  * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
255  * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
256  */
257 function isIndex(value, length) {
258   length = length == null ? MAX_SAFE_INTEGER : length;
259   return !!length &&
260     (typeof value == 'number' || reIsUint.test(value)) &&
261     (value > -1 && value % 1 == 0 && value < length);
262 }
263
264 /**
265  * Checks if the given arguments are from an iteratee call.
266  *
267  * @private
268  * @param {*} value The potential iteratee value argument.
269  * @param {*} index The potential iteratee index or key argument.
270  * @param {*} object The potential iteratee object argument.
271  * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
272  *  else `false`.
273  */
274 function isIterateeCall(value, index, object) {
275   if (!isObject(object)) {
276     return false;
277   }
278   var type = typeof index;
279   if (type == 'number'
280         ? (isArrayLike(object) && isIndex(index, object.length))
281         : (type == 'string' && index in object)
282       ) {
283     return eq(object[index], value);
284   }
285   return false;
286 }
287
288 /**
289  * Checks if `value` is likely a prototype object.
290  *
291  * @private
292  * @param {*} value The value to check.
293  * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
294  */
295 function isPrototype(value) {
296   var Ctor = value && value.constructor,
297       proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
298
299   return value === proto;
300 }
301
302 /**
303  * Performs a
304  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
305  * comparison between two values to determine if they are equivalent.
306  *
307  * @static
308  * @memberOf _
309  * @since 4.0.0
310  * @category Lang
311  * @param {*} value The value to compare.
312  * @param {*} other The other value to compare.
313  * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
314  * @example
315  *
316  * var object = { 'a': 1 };
317  * var other = { 'a': 1 };
318  *
319  * _.eq(object, object);
320  * // => true
321  *
322  * _.eq(object, other);
323  * // => false
324  *
325  * _.eq('a', 'a');
326  * // => true
327  *
328  * _.eq('a', Object('a'));
329  * // => false
330  *
331  * _.eq(NaN, NaN);
332  * // => true
333  */
334 function eq(value, other) {
335   return value === other || (value !== value && other !== other);
336 }
337
338 /**
339  * Checks if `value` is likely an `arguments` object.
340  *
341  * @static
342  * @memberOf _
343  * @since 0.1.0
344  * @category Lang
345  * @param {*} value The value to check.
346  * @returns {boolean} Returns `true` if `value` is an `arguments` object,
347  *  else `false`.
348  * @example
349  *
350  * _.isArguments(function() { return arguments; }());
351  * // => true
352  *
353  * _.isArguments([1, 2, 3]);
354  * // => false
355  */
356 function isArguments(value) {
357   // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
358   return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
359     (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
360 }
361
362 /**
363  * Checks if `value` is classified as an `Array` object.
364  *
365  * @static
366  * @memberOf _
367  * @since 0.1.0
368  * @category Lang
369  * @param {*} value The value to check.
370  * @returns {boolean} Returns `true` if `value` is an array, else `false`.
371  * @example
372  *
373  * _.isArray([1, 2, 3]);
374  * // => true
375  *
376  * _.isArray(document.body.children);
377  * // => false
378  *
379  * _.isArray('abc');
380  * // => false
381  *
382  * _.isArray(_.noop);
383  * // => false
384  */
385 var isArray = Array.isArray;
386
387 /**
388  * Checks if `value` is array-like. A value is considered array-like if it's
389  * not a function and has a `value.length` that's an integer greater than or
390  * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
391  *
392  * @static
393  * @memberOf _
394  * @since 4.0.0
395  * @category Lang
396  * @param {*} value The value to check.
397  * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
398  * @example
399  *
400  * _.isArrayLike([1, 2, 3]);
401  * // => true
402  *
403  * _.isArrayLike(document.body.children);
404  * // => true
405  *
406  * _.isArrayLike('abc');
407  * // => true
408  *
409  * _.isArrayLike(_.noop);
410  * // => false
411  */
412 function isArrayLike(value) {
413   return value != null && isLength(value.length) && !isFunction(value);
414 }
415
416 /**
417  * This method is like `_.isArrayLike` except that it also checks if `value`
418  * is an object.
419  *
420  * @static
421  * @memberOf _
422  * @since 4.0.0
423  * @category Lang
424  * @param {*} value The value to check.
425  * @returns {boolean} Returns `true` if `value` is an array-like object,
426  *  else `false`.
427  * @example
428  *
429  * _.isArrayLikeObject([1, 2, 3]);
430  * // => true
431  *
432  * _.isArrayLikeObject(document.body.children);
433  * // => true
434  *
435  * _.isArrayLikeObject('abc');
436  * // => false
437  *
438  * _.isArrayLikeObject(_.noop);
439  * // => false
440  */
441 function isArrayLikeObject(value) {
442   return isObjectLike(value) && isArrayLike(value);
443 }
444
445 /**
446  * Checks if `value` is classified as a `Function` object.
447  *
448  * @static
449  * @memberOf _
450  * @since 0.1.0
451  * @category Lang
452  * @param {*} value The value to check.
453  * @returns {boolean} Returns `true` if `value` is a function, else `false`.
454  * @example
455  *
456  * _.isFunction(_);
457  * // => true
458  *
459  * _.isFunction(/abc/);
460  * // => false
461  */
462 function isFunction(value) {
463   // The use of `Object#toString` avoids issues with the `typeof` operator
464   // in Safari 8-9 which returns 'object' for typed array and other constructors.
465   var tag = isObject(value) ? objectToString.call(value) : '';
466   return tag == funcTag || tag == genTag;
467 }
468
469 /**
470  * Checks if `value` is a valid array-like length.
471  *
472  * **Note:** This method is loosely based on
473  * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
474  *
475  * @static
476  * @memberOf _
477  * @since 4.0.0
478  * @category Lang
479  * @param {*} value The value to check.
480  * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
481  * @example
482  *
483  * _.isLength(3);
484  * // => true
485  *
486  * _.isLength(Number.MIN_VALUE);
487  * // => false
488  *
489  * _.isLength(Infinity);
490  * // => false
491  *
492  * _.isLength('3');
493  * // => false
494  */
495 function isLength(value) {
496   return typeof value == 'number' &&
497     value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
498 }
499
500 /**
501  * Checks if `value` is the
502  * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
503  * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
504  *
505  * @static
506  * @memberOf _
507  * @since 0.1.0
508  * @category Lang
509  * @param {*} value The value to check.
510  * @returns {boolean} Returns `true` if `value` is an object, else `false`.
511  * @example
512  *
513  * _.isObject({});
514  * // => true
515  *
516  * _.isObject([1, 2, 3]);
517  * // => true
518  *
519  * _.isObject(_.noop);
520  * // => true
521  *
522  * _.isObject(null);
523  * // => false
524  */
525 function isObject(value) {
526   var type = typeof value;
527   return !!value && (type == 'object' || type == 'function');
528 }
529
530 /**
531  * Checks if `value` is object-like. A value is object-like if it's not `null`
532  * and has a `typeof` result of "object".
533  *
534  * @static
535  * @memberOf _
536  * @since 4.0.0
537  * @category Lang
538  * @param {*} value The value to check.
539  * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
540  * @example
541  *
542  * _.isObjectLike({});
543  * // => true
544  *
545  * _.isObjectLike([1, 2, 3]);
546  * // => true
547  *
548  * _.isObjectLike(_.noop);
549  * // => false
550  *
551  * _.isObjectLike(null);
552  * // => false
553  */
554 function isObjectLike(value) {
555   return !!value && typeof value == 'object';
556 }
557
558 /**
559  * This method is like `_.assign` except that it accepts `customizer`
560  * which is invoked to produce the assigned values. If `customizer` returns
561  * `undefined`, assignment is handled by the method instead. The `customizer`
562  * is invoked with five arguments: (objValue, srcValue, key, object, source).
563  *
564  * **Note:** This method mutates `object`.
565  *
566  * @static
567  * @memberOf _
568  * @since 4.0.0
569  * @category Object
570  * @param {Object} object The destination object.
571  * @param {...Object} sources The source objects.
572  * @param {Function} [customizer] The function to customize assigned values.
573  * @returns {Object} Returns `object`.
574  * @see _.assignInWith
575  * @example
576  *
577  * function customizer(objValue, srcValue) {
578  *   return _.isUndefined(objValue) ? srcValue : objValue;
579  * }
580  *
581  * var defaults = _.partialRight(_.assignWith, customizer);
582  *
583  * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
584  * // => { 'a': 1, 'b': 2 }
585  */
586 var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
587   copyObject(source, keys(source), object, customizer);
588 });
589
590 /**
591  * Creates an array of the own enumerable property names of `object`.
592  *
593  * **Note:** Non-object values are coerced to objects. See the
594  * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
595  * for more details.
596  *
597  * @static
598  * @since 0.1.0
599  * @memberOf _
600  * @category Object
601  * @param {Object} object The object to query.
602  * @returns {Array} Returns the array of property names.
603  * @example
604  *
605  * function Foo() {
606  *   this.a = 1;
607  *   this.b = 2;
608  * }
609  *
610  * Foo.prototype.c = 3;
611  *
612  * _.keys(new Foo);
613  * // => ['a', 'b'] (iteration order is not guaranteed)
614  *
615  * _.keys('hi');
616  * // => ['0', '1']
617  */
618 function keys(object) {
619   return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
620 }
621
622 module.exports = assignWith;