Comparing
lodash@4.17.0
...
lodash@4.17.19
files: **/!(*.map|*.min.js)
@@ -1,6 +1,6 @@ | |||
1 | { | 1 | { |
2 | "name": "lodash", | 2 | "name": "lodash", |
3 | "version": "4.17.0", | 3 | "version": "4.17.19", |
4 | "description": "Lodash modular utilities.", | 4 | "description": "Lodash modular utilities.", |
5 | "keywords": "modules, stdlib, util", | 5 | "keywords": "modules, stdlib, util", |
6 | "homepage": "https://lodash.com/", | 6 | "homepage": "https://lodash.com/", |
@@ -8,10 +8,10 @@ | |||
8 | "icon": "https://lodash.com/icon.svg", | 8 | "icon": "https://lodash.com/icon.svg", |
9 | "license": "MIT", | 9 | "license": "MIT", |
10 | "main": "lodash.js", | 10 | "main": "lodash.js", |
11 | "author": "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)", | 11 | "author": "John-David Dalton <john.david.dalton@gmail.com>", |
12 | "contributors": [ | 12 | "contributors": [ |
13 | "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)", | ||
14 | "Mathias Bynens <mathias@qiwi.be> (https://mathiasbynens.be/)" | 13 | "John-David Dalton <john.david.dalton@gmail.com>", |
14 | "Mathias Bynens <mathias@qiwi.be>" | ||
15 | ], | 15 | ], |
16 | "scripts": { "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" } | 16 | "scripts": { "test": "echo \"See https://travis-ci.org/lodash-archive/lodash-cli for testing details.\"" } |
17 | } | 17 | } |
@@ -1,4 +1,4 @@ | |||
1 | # lodash v4.17.0 | 1 | # lodash v4.17.19 |
2 | 2 | ||
3 | The [Lodash](https://lodash.com/) library exported as [Node.js](https://nodejs.org/) modules. | 3 | The [Lodash](https://lodash.com/) library exported as [Node.js](https://nodejs.org/) modules. |
4 | 4 | ||
@@ -28,12 +28,12 @@ | |||
28 | var curryN = require('lodash/fp/curryN'); | 28 | var curryN = require('lodash/fp/curryN'); |
29 | ``` | 29 | ``` |
30 | 30 | ||
31 | See the [package source](https://github.com/lodash/lodash/tree/4.17.0-npm) for more details. | 31 | See the [package source](https://github.com/lodash/lodash/tree/4.17.19-npm) for more details. |
32 | 32 | ||
33 | **Note:**<br> | 33 | **Note:**<br> |
34 | Install [n_](https://www.npmjs.com/package/n_) for Lodash use in the Node.js < 6 REPL. | 34 | Install [n_](https://www.npmjs.com/package/n_) for Lodash use in the Node.js < 6 REPL. |
35 | 35 | ||
36 | ## Support | 36 | ## Support |
37 | 37 | ||
38 | Tested in Chrome 53-54, Firefox 48-49, IE 11, Edge 14, Safari 9-10, Node.js 6-7, & PhantomJS 2.1.1.<br> | 38 | Tested in Chrome 74-75, Firefox 66-67, IE 11, Edge 18, Safari 11-12, & Node.js 8-12.<br> |
39 | Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available. | 39 | Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available. |
@@ -1,4 +1,4 @@ | |||
1 | Copyright JS Foundation and other contributors <https://js.foundation/> | 1 | Copyright OpenJS Foundation and other contributors <https://openjsf.org/> |
2 | 2 | ||
3 | Based on Underscore.js, copyright Jeremy Ashkenas, | 3 | Based on Underscore.js, copyright Jeremy Ashkenas, |
4 | DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/> | 4 | DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/> |
@@ -38,8 +38,8 @@ | |||
38 | reOptMod = rsModifier + '?', | 38 | reOptMod = rsModifier + '?', |
39 | rsOptVar = '[' + rsVarRange + ']?', | 39 | rsOptVar = '[' + rsVarRange + ']?', |
40 | rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', | 40 | rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', |
41 | rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)', | ||
42 | rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)', | 41 | rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])', |
42 | rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])', | ||
43 | rsSeq = rsOptVar + reOptMod + rsOptJoin, | 43 | rsSeq = rsOptVar + reOptMod + rsOptJoin, |
44 | rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq; | 44 | rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq; |
45 | 45 |
@@ -108,9 +108,11 @@ | |||
108 | function remainingWait(time) { | 108 | function remainingWait(time) { |
109 | var timeSinceLastCall = time - lastCallTime, | 109 | var timeSinceLastCall = time - lastCallTime, |
110 | timeSinceLastInvoke = time - lastInvokeTime, | 110 | timeSinceLastInvoke = time - lastInvokeTime, |
111 | result = wait - timeSinceLastCall; | 111 | timeWaiting = wait - timeSinceLastCall; |
112 | 112 | ||
113 | return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; | 113 | return maxing |
114 | ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) | ||
115 | : timeWaiting; | ||
114 | } | 116 | } |
115 | 117 | ||
116 | function shouldInvoke(time) { | 118 | function shouldInvoke(time) { |
@@ -171,6 +173,7 @@ | |||
171 | } | 173 | } |
172 | if (maxing) { | 174 | if (maxing) { |
173 | // Handle invocations in a tight loop. | 175 | // Handle invocations in a tight loop. |
176 | clearTimeout(timerId); | ||
174 | timerId = setTimeout(timerExpired, wait); | 177 | timerId = setTimeout(timerExpired, wait); |
175 | return invokeFunc(lastCallTime); | 178 | return invokeFunc(lastCallTime); |
176 | } | 179 | } |
@@ -1,8 +1,14 @@ | |||
1 | var apply = require('./_apply'), | ||
2 | assignInDefaults = require('./_assignInDefaults'), | ||
3 | assignInWith = require('./assignInWith'), | ||
4 | baseRest = require('./_baseRest'); | 1 | var baseRest = require('./_baseRest'), |
2 | eq = require('./eq'), | ||
3 | isIterateeCall = require('./_isIterateeCall'), | ||
4 | keysIn = require('./keysIn'); | ||
5 | 5 | ||
6 | /** Used for built-in method references. */ | ||
7 | var objectProto = Object.prototype; | ||
8 | |||
9 | /** Used to check objects for own properties. */ | ||
10 | var hasOwnProperty = objectProto.hasOwnProperty; | ||
11 | |||
6 | /** | 12 | /** |
7 | * Assigns own and inherited enumerable string keyed properties of source | 13 | * Assigns own and inherited enumerable string keyed properties of source |
8 | * objects to the destination object for all destination properties that | 14 | * objects to the destination object for all destination properties that |
@@ -24,9 +30,35 @@ | |||
24 | * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); | 30 | * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); |
25 | * // => { 'a': 1, 'b': 2 } | 31 | * // => { 'a': 1, 'b': 2 } |
26 | */ | 32 | */ |
27 | var defaults = baseRest(function(args) { | ||
28 | args.push(undefined, assignInDefaults); | ||
29 | return apply(assignInWith, undefined, args); | 33 | var defaults = baseRest(function(object, sources) { |
34 | object = Object(object); | ||
35 | |||
36 | var index = -1; | ||
37 | var length = sources.length; | ||
38 | var guard = length > 2 ? sources[2] : undefined; | ||
39 | |||
40 | if (guard && isIterateeCall(sources[0], sources[1], guard)) { | ||
41 | length = 1; | ||
42 | } | ||
43 | |||
44 | while (++index < length) { | ||
45 | var source = sources[index]; | ||
46 | var props = keysIn(source); | ||
47 | var propsIndex = -1; | ||
48 | var propsLength = props.length; | ||
49 | |||
50 | while (++propsIndex < propsLength) { | ||
51 | var key = props[propsIndex]; | ||
52 | var value = object[key]; | ||
53 | |||
54 | if (value === undefined || | ||
55 | (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { | ||
56 | object[key] = source[key]; | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | |||
61 | return object; | ||
30 | }); | 62 | }); |
31 | 63 | ||
32 | module.exports = defaults; | 64 | module.exports = defaults; |
@@ -1,9 +1,7 @@ | |||
1 | var memoizeCapped = require('./_memoizeCapped'), | ||
2 | toString = require('./toString'); | 1 | var memoizeCapped = require('./_memoizeCapped'); |
3 | 2 | ||
4 | /** Used to match property names within property paths. */ | 3 | /** Used to match property names within property paths. */ |
5 | var reLeadingDot = /^\./, | ||
6 | rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; | 4 | var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; |
7 | 5 | ||
8 | /** Used to match backslashes in property paths. */ | 6 | /** Used to match backslashes in property paths. */ |
9 | var reEscapeChar = /\\(\\)?/g; | 7 | var reEscapeChar = /\\(\\)?/g; |
@@ -16,14 +14,12 @@ | |||
16 | * @returns {Array} Returns the property path array. | 14 | * @returns {Array} Returns the property path array. |
17 | */ | 15 | */ |
18 | var stringToPath = memoizeCapped(function(string) { | 16 | var stringToPath = memoizeCapped(function(string) { |
19 | string = toString(string); | ||
20 | |||
21 | var result = []; | 17 | var result = []; |
22 | if (reLeadingDot.test(string)) { | 18 | if (string.charCodeAt(0) === 46 /* . */) { |
23 | result.push(''); | 19 | result.push(''); |
24 | } | 20 | } |
25 | string.replace(rePropName, function(match, number, quote, string) { | ||
26 | result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); | 21 | string.replace(rePropName, function(match, number, quote, subString) { |
22 | result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); | ||
27 | }); | 23 | }); |
28 | return result; | 24 | return result; |
29 | }); | 25 | }); |
@@ -1,6 +1,6 @@ | |||
1 | var apply = require('./_apply'), | 1 | var apply = require('./_apply'), |
2 | baseRest = require('./_baseRest'), | 2 | baseRest = require('./_baseRest'), |
3 | mergeDefaults = require('./_mergeDefaults'), | 3 | customDefaultsMerge = require('./_customDefaultsMerge'), |
4 | mergeWith = require('./mergeWith'); | 4 | mergeWith = require('./mergeWith'); |
5 | 5 | ||
6 | /** | 6 | /** |
@@ -23,7 +23,7 @@ | |||
23 | * // => { 'a': { 'b': 2, 'c': 3 } } | 23 | * // => { 'a': { 'b': 2, 'c': 3 } } |
24 | */ | 24 | */ |
25 | var defaultsDeep = baseRest(function(args) { | 25 | var defaultsDeep = baseRest(function(args) { |
26 | args.push(undefined, mergeDefaults); | 26 | args.push(undefined, customDefaultsMerge); |
27 | return apply(mergeWith, undefined, args); | 27 | return apply(mergeWith, undefined, args); |
28 | }); | 28 | }); |
29 | 29 |
@@ -10,7 +10,7 @@ | |||
10 | * @returns {*} Returns the parent value. | 10 | * @returns {*} Returns the parent value. |
11 | */ | 11 | */ |
12 | function parent(object, path) { | 12 | function parent(object, path) { |
13 | return path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); | 13 | return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); |
14 | } | 14 | } |
15 | 15 | ||
16 | module.exports = parent; | 16 | module.exports = parent; |
@@ -15,6 +15,14 @@ | |||
15 | /** Used to access faster Node.js helpers. */ | 15 | /** Used to access faster Node.js helpers. */ |
16 | var nodeUtil = (function() { | 16 | var nodeUtil = (function() { |
17 | try { | 17 | try { |
18 | // Use `util.types` for Node.js 10+. | ||
19 | var types = freeModule && freeModule.require && freeModule.require('util').types; | ||
20 | |||
21 | if (types) { | ||
22 | return types; | ||
23 | } | ||
24 | |||
25 | // Legacy `process.binding('util')` for Node.js < 10. | ||
18 | return freeProcess && freeProcess.binding && freeProcess.binding('util'); | 26 | return freeProcess && freeProcess.binding && freeProcess.binding('util'); |
19 | } catch (e) {} | 27 | } catch (e) {} |
20 | }()); | 28 | }()); |
@@ -2,9 +2,6 @@ | |||
2 | getView = require('./_getView'), | 2 | getView = require('./_getView'), |
3 | isArray = require('./isArray'); | 3 | isArray = require('./isArray'); |
4 | 4 | ||
5 | /** Used as the size to enable large array optimizations. */ | ||
6 | var LARGE_ARRAY_SIZE = 200; | ||
7 | |||
8 | /** Used to indicate the type of lazy iteratees. */ | 5 | /** Used to indicate the type of lazy iteratees. */ |
9 | var LAZY_FILTER_FLAG = 1, | 6 | var LAZY_FILTER_FLAG = 1, |
10 | LAZY_MAP_FLAG = 2; | 7 | LAZY_MAP_FLAG = 2; |
@@ -36,8 +33,7 @@ | |||
36 | resIndex = 0, | 33 | resIndex = 0, |
37 | takeCount = nativeMin(length, this.__takeCount__); | 34 | takeCount = nativeMin(length, this.__takeCount__); |
38 | 35 | ||
39 | if (!isArr || arrLength < LARGE_ARRAY_SIZE || | ||
40 | (arrLength == length && takeCount == length)) { | 36 | if (!isArr || (!isRight && arrLength == length && takeCount == length)) { |
41 | return baseWrapperValue(array, this.__actions__); | 37 | return baseWrapperValue(array, this.__actions__); |
42 | } | 38 | } |
43 | var result = []; | 39 | var result = []; |
@@ -13,10 +13,13 @@ | |||
13 | * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. | 13 | * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. |
14 | */ | 14 | */ |
15 | function isIndex(value, length) { | 15 | function isIndex(value, length) { |
16 | var type = typeof value; | ||
16 | length = length == null ? MAX_SAFE_INTEGER : length; | 17 | length = length == null ? MAX_SAFE_INTEGER : length; |
18 | |||
17 | return !!length && | 19 | return !!length && |
18 | (typeof value == 'number' || reIsUint.test(value)) && | ||
19 | (value > -1 && value % 1 == 0 && value < length); | 20 | (type == 'number' || |
21 | (type != 'symbol' && reIsUint.test(value))) && | ||
22 | (value > -1 && value % 1 == 0 && value < length); | ||
20 | } | 23 | } |
21 | 24 | ||
22 | module.exports = isIndex; | 25 | module.exports = isIndex; |
@@ -1,8 +1,6 @@ | |||
1 | var cloneArrayBuffer = require('./_cloneArrayBuffer'), | 1 | var cloneArrayBuffer = require('./_cloneArrayBuffer'), |
2 | cloneDataView = require('./_cloneDataView'), | 2 | cloneDataView = require('./_cloneDataView'), |
3 | cloneMap = require('./_cloneMap'), | ||
4 | cloneRegExp = require('./_cloneRegExp'), | 3 | cloneRegExp = require('./_cloneRegExp'), |
5 | cloneSet = require('./_cloneSet'), | ||
6 | cloneSymbol = require('./_cloneSymbol'), | 4 | cloneSymbol = require('./_cloneSymbol'), |
7 | cloneTypedArray = require('./_cloneTypedArray'); | 5 | cloneTypedArray = require('./_cloneTypedArray'); |
8 | 6 | ||
@@ -32,16 +30,15 @@ | |||
32 | * Initializes an object clone based on its `toStringTag`. | 30 | * Initializes an object clone based on its `toStringTag`. |
33 | * | 31 | * |
34 | * **Note:** This function only supports cloning values with tags of | 32 | * **Note:** This function only supports cloning values with tags of |
35 | * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. | 33 | * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. |
36 | * | 34 | * |
37 | * @private | 35 | * @private |
38 | * @param {Object} object The object to clone. | 36 | * @param {Object} object The object to clone. |
39 | * @param {string} tag The `toStringTag` of the object to clone. | 37 | * @param {string} tag The `toStringTag` of the object to clone. |
40 | * @param {Function} cloneFunc The function to clone values. | ||
41 | * @param {boolean} [isDeep] Specify a deep clone. | 38 | * @param {boolean} [isDeep] Specify a deep clone. |
42 | * @returns {Object} Returns the initialized clone. | 39 | * @returns {Object} Returns the initialized clone. |
43 | */ | 40 | */ |
44 | function initCloneByTag(object, tag, cloneFunc, isDeep) { | 41 | function initCloneByTag(object, tag, isDeep) { |
45 | var Ctor = object.constructor; | 42 | var Ctor = object.constructor; |
46 | switch (tag) { | 43 | switch (tag) { |
47 | case arrayBufferTag: | 44 | case arrayBufferTag: |
@@ -60,7 +57,7 @@ | |||
60 | return cloneTypedArray(object, isDeep); | 57 | return cloneTypedArray(object, isDeep); |
61 | 58 | ||
62 | case mapTag: | 59 | case mapTag: |
63 | return cloneMap(object, isDeep, cloneFunc); | 60 | return new Ctor; |
64 | 61 | ||
65 | case numberTag: | 62 | case numberTag: |
66 | case stringTag: | 63 | case stringTag: |
@@ -70,7 +67,7 @@ | |||
70 | return cloneRegExp(object); | 67 | return cloneRegExp(object); |
71 | 68 | ||
72 | case setTag: | 69 | case setTag: |
73 | return cloneSet(object, isDeep, cloneFunc); | 70 | return new Ctor; |
74 | 71 | ||
75 | case symbolTag: | 72 | case symbolTag: |
76 | return cloneSymbol(object); | 73 | return cloneSymbol(object); |
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | function initCloneArray(array) { | 14 | function initCloneArray(array) { |
15 | var length = array.length, | 15 | var length = array.length, |
16 | result = array.constructor(length); | 16 | result = new array.constructor(length); |
17 | 17 | ||
18 | // Add properties assigned by `RegExp#exec`. | 18 | // Add properties assigned by `RegExp#exec`. |
19 | if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { | 19 | if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { |
@@ -17,7 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | function hashHas(key) { | 18 | function hashHas(key) { |
19 | var data = this.__data__; | 19 | var data = this.__data__; |
20 | return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); | 20 | return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); |
21 | } | 21 | } |
22 | 22 | ||
23 | module.exports = hashHas; | 23 | module.exports = hashHas; |
@@ -2,7 +2,17 @@ | |||
2 | createInverter = require('./_createInverter'), | 2 | createInverter = require('./_createInverter'), |
3 | identity = require('./identity'); | 3 | identity = require('./identity'); |
4 | 4 | ||
5 | /** Used for built-in method references. */ | ||
6 | var objectProto = Object.prototype; | ||
7 | |||
5 | /** | 8 | /** |
9 | * Used to resolve the | ||
10 | * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) | ||
11 | * of values. | ||
12 | */ | ||
13 | var nativeObjectToString = objectProto.toString; | ||
14 | |||
15 | /** | ||
6 | * Creates an object composed of the inverted keys and values of `object`. | 16 | * Creates an object composed of the inverted keys and values of `object`. |
7 | * If `object` contains duplicate values, subsequent values overwrite | 17 | * If `object` contains duplicate values, subsequent values overwrite |
8 | * property assignments of previous values. | 18 | * property assignments of previous values. |
@@ -21,6 +31,11 @@ | |||
21 | * // => { '1': 'c', '2': 'b' } | 31 | * // => { '1': 'c', '2': 'b' } |
22 | */ | 32 | */ |
23 | var invert = createInverter(function(result, value, key) { | 33 | var invert = createInverter(function(result, value, key) { |
34 | if (value != null && | ||
35 | typeof value.toString != 'function') { | ||
36 | value = nativeObjectToString.call(value); | ||
37 | } | ||
38 | |||
24 | result[value] = key; | 39 | result[value] = key; |
25 | }, constant(identity)); | 40 | }, constant(identity)); |
26 | 41 |
@@ -8,6 +8,13 @@ | |||
8 | var hasOwnProperty = objectProto.hasOwnProperty; | 8 | var hasOwnProperty = objectProto.hasOwnProperty; |
9 | 9 | ||
10 | /** | 10 | /** |
11 | * Used to resolve the | ||
12 | * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) | ||
13 | * of values. | ||
14 | */ | ||
15 | var nativeObjectToString = objectProto.toString; | ||
16 | |||
17 | /** | ||
11 | * This method is like `_.invert` except that the inverted object is generated | 18 | * This method is like `_.invert` except that the inverted object is generated |
12 | * from the results of running each element of `object` thru `iteratee`. The | 19 | * from the results of running each element of `object` thru `iteratee`. The |
13 | * corresponding inverted value of each inverted key is an array of keys | 20 | * corresponding inverted value of each inverted key is an array of keys |
@@ -34,6 +41,11 @@ | |||
34 | * // => { 'group1': ['a', 'c'], 'group2': ['b'] } | 41 | * // => { 'group1': ['a', 'c'], 'group2': ['b'] } |
35 | */ | 42 | */ |
36 | var invertBy = createInverter(function(result, value, key) { | 43 | var invertBy = createInverter(function(result, value, key) { |
44 | if (value != null && | ||
45 | typeof value.toString != 'function') { | ||
46 | value = nativeObjectToString.call(value); | ||
47 | } | ||
48 | |||
37 | if (hasOwnProperty.call(result, value)) { | 49 | if (hasOwnProperty.call(result, value)) { |
38 | result[value].push(key); | 50 | result[value].push(key); |
39 | } else { | 51 | } else { |
@@ -2,8 +2,7 @@ | |||
2 | baseEach = require('./_baseEach'), | 2 | baseEach = require('./_baseEach'), |
3 | baseInvoke = require('./_baseInvoke'), | 3 | baseInvoke = require('./_baseInvoke'), |
4 | baseRest = require('./_baseRest'), | 4 | baseRest = require('./_baseRest'), |
5 | isArrayLike = require('./isArrayLike'), | ||
6 | isKey = require('./_isKey'); | 5 | isArrayLike = require('./isArrayLike'); |
7 | 6 | ||
8 | /** | 7 | /** |
9 | * Invokes the method at `path` of each element in `collection`, returning | 8 | * Invokes the method at `path` of each element in `collection`, returning |
@@ -31,12 +30,10 @@ | |||
31 | var invokeMap = baseRest(function(collection, path, args) { | 30 | var invokeMap = baseRest(function(collection, path, args) { |
32 | var index = -1, | 31 | var index = -1, |
33 | isFunc = typeof path == 'function', | 32 | isFunc = typeof path == 'function', |
34 | isProp = isKey(path), | ||
35 | result = isArrayLike(collection) ? Array(collection.length) : []; | 33 | result = isArrayLike(collection) ? Array(collection.length) : []; |
36 | 34 | ||
37 | baseEach(collection, function(value) { | 35 | baseEach(collection, function(value) { |
38 | var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); | ||
39 | result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args); | 36 | result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args); |
40 | }); | 37 | }); |
41 | return result; | 38 | return result; |
42 | }); | 39 | }); |
@@ -1,5 +1,5 @@ | |||
1 | /** Used to detect strings that need a more robust regexp to match words. */ | 1 | /** Used to detect strings that need a more robust regexp to match words. */ |
2 | var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; | 2 | var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; |
3 | 3 | ||
4 | /** | 4 | /** |
5 | * Checks if `string` contains a word composed of Unicode symbols. | 5 | * Checks if `string` contains a word composed of Unicode symbols. |
@@ -2,7 +2,6 @@ | |||
2 | isArguments = require('./isArguments'), | 2 | isArguments = require('./isArguments'), |
3 | isArray = require('./isArray'), | 3 | isArray = require('./isArray'), |
4 | isIndex = require('./_isIndex'), | 4 | isIndex = require('./_isIndex'), |
5 | isKey = require('./_isKey'), | ||
6 | isLength = require('./isLength'), | 5 | isLength = require('./isLength'), |
7 | toKey = require('./_toKey'); | 6 | toKey = require('./_toKey'); |
8 | 7 | ||
@@ -16,7 +15,7 @@ | |||
16 | * @returns {boolean} Returns `true` if `path` exists, else `false`. | 15 | * @returns {boolean} Returns `true` if `path` exists, else `false`. |
17 | */ | 16 | */ |
18 | function hasPath(object, path, hasFunc) { | 17 | function hasPath(object, path, hasFunc) { |
19 | path = isKey(path, object) ? [path] : castPath(path); | 18 | path = castPath(path, object); |
20 | 19 | ||
21 | var index = -1, | 20 | var index = -1, |
22 | length = path.length, | 21 | length = path.length, |
@@ -1,6 +1,12 @@ | |||
1 | var overArg = require('./_overArg'), | 1 | var arrayFilter = require('./_arrayFilter'), |
2 | stubArray = require('./stubArray'); | 2 | stubArray = require('./stubArray'); |
3 | 3 | ||
4 | /** Used for built-in method references. */ | ||
5 | var objectProto = Object.prototype; | ||
6 | |||
7 | /** Built-in value references. */ | ||
8 | var propertyIsEnumerable = objectProto.propertyIsEnumerable; | ||
9 | |||
4 | /* Built-in method references for those with the same name as other `lodash` methods. */ | 10 | /* Built-in method references for those with the same name as other `lodash` methods. */ |
5 | var nativeGetSymbols = Object.getOwnPropertySymbols; | 11 | var nativeGetSymbols = Object.getOwnPropertySymbols; |
6 | 12 | ||
@@ -11,6 +17,14 @@ | |||
11 | * @param {Object} object The object to query. | 17 | * @param {Object} object The object to query. |
12 | * @returns {Array} Returns the array of symbols. | 18 | * @returns {Array} Returns the array of symbols. |
13 | */ | 19 | */ |
14 | var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; | 20 | var getSymbols = !nativeGetSymbols ? stubArray : function(object) { |
21 | if (object == null) { | ||
22 | return []; | ||
23 | } | ||
24 | object = Object(object); | ||
25 | return arrayFilter(nativeGetSymbols(object), function(symbol) { | ||
26 | return propertyIsEnumerable.call(object, symbol); | ||
27 | }); | ||
28 | }; | ||
15 | 29 | ||
16 | module.exports = getSymbols; | 30 | module.exports = getSymbols; |
@@ -8,7 +8,7 @@ | |||
8 | * date objects, error objects, maps, numbers, `Object` objects, regexes, | 8 | * date objects, error objects, maps, numbers, `Object` objects, regexes, |
9 | * sets, strings, symbols, and typed arrays. `Object` objects are compared | 9 | * sets, strings, symbols, and typed arrays. `Object` objects are compared |
10 | * by their own, not inherited, enumerable properties. Functions and DOM | 10 | * by their own, not inherited, enumerable properties. Functions and DOM |
11 | * nodes are **not** supported. | 11 | * nodes are compared by strict equality, i.e. `===`. |
12 | * | 12 | * |
13 | * @static | 13 | * @static |
14 | * @memberOf _ | 14 | * @memberOf _ |
@@ -1,4 +1,4 @@ | |||
1 | var keys = require('./keys'); | 1 | var getAllKeys = require('./_getAllKeys'); |
2 | 2 | ||
3 | /** Used to compose bitmasks for value comparisons. */ | 3 | /** Used to compose bitmasks for value comparisons. */ |
4 | var COMPARE_PARTIAL_FLAG = 1; | 4 | var COMPARE_PARTIAL_FLAG = 1; |
@@ -24,9 +24,9 @@ | |||
24 | */ | 24 | */ |
25 | function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { | 25 | function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { |
26 | var isPartial = bitmask & COMPARE_PARTIAL_FLAG, | 26 | var isPartial = bitmask & COMPARE_PARTIAL_FLAG, |
27 | objProps = keys(object), | 27 | objProps = getAllKeys(object), |
28 | objLength = objProps.length, | 28 | objLength = objProps.length, |
29 | othProps = keys(other), | 29 | othProps = getAllKeys(other), |
30 | othLength = othProps.length; | 30 | othLength = othProps.length; |
31 | 31 | ||
32 | if (objLength != othLength && !isPartial) { | 32 | if (objLength != othLength && !isPartial) { |
@@ -83,7 +83,7 @@ | |||
83 | thisArg = newData[2]; | 83 | thisArg = newData[2]; |
84 | partials = newData[3]; | 84 | partials = newData[3]; |
85 | holders = newData[4]; | 85 | holders = newData[4]; |
86 | arity = newData[9] = newData[9] == null | 86 | arity = newData[9] = newData[9] === undefined |
87 | ? (isBindKey ? 0 : func.length) | 87 | ? (isBindKey ? 0 : func.length) |
88 | : nativeMax(newData[9] - length, 0); | 88 | : nativeMax(newData[9] - length, 0); |
89 | 89 |
@@ -1,9 +1,11 @@ | |||
1 | var toInteger = require('./toInteger'), | 1 | var root = require('./_root'), |
2 | toInteger = require('./toInteger'), | ||
2 | toNumber = require('./toNumber'), | 3 | toNumber = require('./toNumber'), |
3 | toString = require('./toString'); | 4 | toString = require('./toString'); |
4 | 5 | ||
5 | /* Built-in method references for those with the same name as other `lodash` methods. */ | 6 | /* Built-in method references for those with the same name as other `lodash` methods. */ |
6 | var nativeMin = Math.min; | 7 | var nativeIsFinite = root.isFinite, |
8 | nativeMin = Math.min; | ||
7 | 9 | ||
8 | /** | 10 | /** |
9 | * Creates a function like `_.round`. | 11 | * Creates a function like `_.round`. |
@@ -16,8 +18,8 @@ | |||
16 | var func = Math[methodName]; | 18 | var func = Math[methodName]; |
17 | return function(number, precision) { | 19 | return function(number, precision) { |
18 | number = toNumber(number); | 20 | number = toNumber(number); |
19 | precision = nativeMin(toInteger(precision), 292); | ||
20 | if (precision) { | 21 | precision = precision == null ? 0 : nativeMin(toInteger(precision), 292); |
22 | if (precision && nativeIsFinite(number)) { | ||
21 | // Shift with exponential notation to avoid floating-point issues. | 23 | // Shift with exponential notation to avoid floating-point issues. |
22 | // See [MDN](https://mdn.io/round#Examples) for more details. | 24 | // See [MDN](https://mdn.io/round#Examples) for more details. |
23 | var pair = (toString(number) + 'e').split('e'), | 25 | var pair = (toString(number) + 'e').split('e'), |
@@ -5,9 +5,6 @@ | |||
5 | isArray = require('./isArray'), | 5 | isArray = require('./isArray'), |
6 | isLaziable = require('./_isLaziable'); | 6 | isLaziable = require('./_isLaziable'); |
7 | 7 | ||
8 | /** Used as the size to enable large array optimizations. */ | ||
9 | var LARGE_ARRAY_SIZE = 200; | ||
10 | |||
11 | /** Error message constants. */ | 8 | /** Error message constants. */ |
12 | var FUNC_ERROR_TEXT = 'Expected a function'; | 9 | var FUNC_ERROR_TEXT = 'Expected a function'; |
13 | 10 | ||
@@ -64,8 +61,7 @@ | |||
64 | var args = arguments, | 61 | var args = arguments, |
65 | value = args[0]; | 62 | value = args[0]; |
66 | 63 | ||
67 | if (wrapper && args.length == 1 && | ||
68 | isArray(value) && value.length >= LARGE_ARRAY_SIZE) { | 64 | if (wrapper && args.length == 1 && isArray(value)) { |
69 | return wrapper.plant(value).value(); | 65 | return wrapper.plant(value).value(); |
70 | } | 66 | } |
71 | var index = 0, | 67 | var index = 0, |
@@ -1,15 +1,21 @@ | |||
1 | var isArray = require('./isArray'), | 1 | var isArray = require('./isArray'), |
2 | stringToPath = require('./_stringToPath'); | 2 | isKey = require('./_isKey'), |
3 | stringToPath = require('./_stringToPath'), | ||
4 | toString = require('./toString'); | ||
3 | 5 | ||
4 | /** | 6 | /** |
5 | * Casts `value` to a path array if it's not one. | 7 | * Casts `value` to a path array if it's not one. |
6 | * | 8 | * |
7 | * @private | 9 | * @private |
8 | * @param {*} value The value to inspect. | 10 | * @param {*} value The value to inspect. |
11 | * @param {Object} [object] The object to query keys on. | ||
9 | * @returns {Array} Returns the cast property path array. | 12 | * @returns {Array} Returns the cast property path array. |
10 | */ | 13 | */ |
11 | function castPath(value) { | ||
12 | return isArray(value) ? value : stringToPath(value); | 14 | function castPath(value, object) { |
15 | if (isArray(value)) { | ||
16 | return value; | ||
17 | } | ||
18 | return isKey(value, object) ? [value] : stringToPath(toString(value)); | ||
13 | } | 19 | } |
14 | 20 | ||
15 | module.exports = castPath; | 21 | module.exports = castPath; |
@@ -1,6 +1,9 @@ | |||
1 | var baseClone = require('./_baseClone'), | 1 | var arrayMap = require('./_arrayMap'), |
2 | baseClone = require('./_baseClone'), | ||
2 | baseUnset = require('./_baseUnset'), | 3 | baseUnset = require('./_baseUnset'), |
4 | castPath = require('./_castPath'), | ||
3 | copyObject = require('./_copyObject'), | 5 | copyObject = require('./_copyObject'), |
6 | customOmitClone = require('./_customOmitClone'), | ||
4 | flatRest = require('./_flatRest'), | 7 | flatRest = require('./_flatRest'), |
5 | getAllKeysIn = require('./_getAllKeysIn'); | 8 | getAllKeysIn = require('./_getAllKeysIn'); |
6 | 9 | ||
@@ -34,9 +37,16 @@ | |||
34 | if (object == null) { | 37 | if (object == null) { |
35 | return result; | 38 | return result; |
36 | } | 39 | } |
40 | var isDeep = false; | ||
41 | paths = arrayMap(paths, function(path) { | ||
42 | path = castPath(path, object); | ||
43 | isDeep || (isDeep = path.length > 1); | ||
44 | return path; | ||
45 | }); | ||
37 | copyObject(object, getAllKeysIn(object), result); | 46 | copyObject(object, getAllKeysIn(object), result); |
38 | result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG); | ||
39 | 47 | if (isDeep) { | |
48 | result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); | ||
49 | } | ||
40 | var length = paths.length; | 50 | var length = paths.length; |
41 | while (length--) { | 51 | while (length--) { |
42 | baseUnset(result, paths[length]); | 52 | baseUnset(result, paths[length]); |
@@ -1,15 +1,8 @@ | |||
1 | var castPath = require('./_castPath'), | 1 | var castPath = require('./_castPath'), |
2 | isKey = require('./_isKey'), | ||
3 | last = require('./last'), | 2 | last = require('./last'), |
4 | parent = require('./_parent'), | 3 | parent = require('./_parent'), |
5 | toKey = require('./_toKey'); | 4 | toKey = require('./_toKey'); |
6 | 5 | ||
7 | /** Used for built-in method references. */ | ||
8 | var objectProto = Object.prototype; | ||
9 | |||
10 | /** Used to check objects for own properties. */ | ||
11 | var hasOwnProperty = objectProto.hasOwnProperty; | ||
12 | |||
13 | /** | 6 | /** |
14 | * The base implementation of `_.unset`. | 7 | * The base implementation of `_.unset`. |
15 | * | 8 | * |
@@ -19,11 +12,9 @@ | |||
19 | * @returns {boolean} Returns `true` if the property is deleted, else `false`. | 12 | * @returns {boolean} Returns `true` if the property is deleted, else `false`. |
20 | */ | 13 | */ |
21 | function baseUnset(object, path) { | 14 | function baseUnset(object, path) { |
22 | path = isKey(path, object) ? [path] : castPath(path); | 15 | path = castPath(path, object); |
23 | object = parent(object, path); | 16 | object = parent(object, path); |
24 | |||
25 | var key = toKey(last(path)); | ||
26 | return !(object != null && hasOwnProperty.call(object, key)) || delete object[key]; | 17 | return object == null || delete object[toKey(last(path))]; |
27 | } | 18 | } |
28 | 19 | ||
29 | module.exports = baseUnset; | 20 | module.exports = baseUnset; |
@@ -1,7 +1,5 @@ | |||
1 | var arrayMap = require('./_arrayMap'), | ||
2 | basePick = require('./_basePick'), | ||
3 | flatRest = require('./_flatRest'), | ||
4 | toKey = require('./_toKey'); | 1 | var basePick = require('./_basePick'), |
2 | flatRest = require('./_flatRest'); | ||
5 | 3 | ||
6 | /** | 4 | /** |
7 | * Creates an object composed of the picked `object` properties. | 5 | * Creates an object composed of the picked `object` properties. |
@@ -21,7 +19,7 @@ | |||
21 | * // => { 'a': 1, 'c': 3 } | 19 | * // => { 'a': 1, 'c': 3 } |
22 | */ | 20 | */ |
23 | var pick = flatRest(function(object, paths) { | 21 | var pick = flatRest(function(object, paths) { |
24 | return object == null ? {} : basePick(object, arrayMap(paths, toKey)); | 22 | return object == null ? {} : basePick(object, paths); |
25 | }); | 23 | }); |
26 | 24 | ||
27 | module.exports = pick; | 25 | module.exports = pick; |
@@ -1,4 +1,5 @@ | |||
1 | var baseIteratee = require('./_baseIteratee'), | 1 | var arrayMap = require('./_arrayMap'), |
2 | baseIteratee = require('./_baseIteratee'), | ||
2 | basePickBy = require('./_basePickBy'), | 3 | basePickBy = require('./_basePickBy'), |
3 | getAllKeysIn = require('./_getAllKeysIn'); | 4 | getAllKeysIn = require('./_getAllKeysIn'); |
4 | 5 | ||
@@ -21,7 +22,16 @@ | |||
21 | * // => { 'a': 1, 'c': 3 } | 22 | * // => { 'a': 1, 'c': 3 } |
22 | */ | 23 | */ |
23 | function pickBy(object, predicate) { | 24 | function pickBy(object, predicate) { |
24 | return object == null ? {} : basePickBy(object, getAllKeysIn(object), baseIteratee(predicate)); | 25 | if (object == null) { |
26 | return {}; | ||
27 | } | ||
28 | var props = arrayMap(getAllKeysIn(object), function(prop) { | ||
29 | return [prop]; | ||
30 | }); | ||
31 | predicate = baseIteratee(predicate); | ||
32 | return basePickBy(object, props, function(value, path) { | ||
33 | return predicate(value, path[0]); | ||
34 | }); | ||
25 | } | 35 | } |
26 | 36 | ||
27 | module.exports = pickBy; | 37 | module.exports = pickBy; |
@@ -1,7 +1,6 @@ | |||
1 | var assignValue = require('./_assignValue'), | 1 | var assignValue = require('./_assignValue'), |
2 | castPath = require('./_castPath'), | 2 | castPath = require('./_castPath'), |
3 | isIndex = require('./_isIndex'), | 3 | isIndex = require('./_isIndex'), |
4 | isKey = require('./_isKey'), | ||
5 | isObject = require('./isObject'), | 4 | isObject = require('./isObject'), |
6 | toKey = require('./_toKey'); | 5 | toKey = require('./_toKey'); |
7 | 6 | ||
@@ -19,7 +18,7 @@ | |||
19 | if (!isObject(object)) { | 18 | if (!isObject(object)) { |
20 | return object; | 19 | return object; |
21 | } | 20 | } |
22 | path = isKey(path, object) ? [path] : castPath(path); | 21 | path = castPath(path, object); |
23 | 22 | ||
24 | var index = -1, | 23 | var index = -1, |
25 | length = path.length, | 24 | length = path.length, |
@@ -1,9 +1,5 @@ | |||
1 | var castPath = require('./_castPath'), | ||
2 | isIndex = require('./_isIndex'), | ||
3 | isKey = require('./_isKey'), | ||
4 | last = require('./last'), | ||
5 | parent = require('./_parent'), | ||
6 | toKey = require('./_toKey'); | 1 | var baseUnset = require('./_baseUnset'), |
2 | isIndex = require('./_isIndex'); | ||
7 | 3 | ||
8 | /** Used for built-in method references. */ | 4 | /** Used for built-in method references. */ |
9 | var arrayProto = Array.prototype; | 5 | var arrayProto = Array.prototype; |
@@ -30,18 +26,9 @@ | |||
30 | var previous = index; | 26 | var previous = index; |
31 | if (isIndex(index)) { | 27 | if (isIndex(index)) { |
32 | splice.call(array, index, 1); | 28 | splice.call(array, index, 1); |
29 | } else { | ||
30 | baseUnset(array, index); | ||
33 | } | 31 | } |
34 | else if (!isKey(index, array)) { | ||
35 | var path = castPath(index), | ||
36 | object = parent(array, path); | ||
37 | |||
38 | if (object != null) { | ||
39 | delete object[toKey(last(path))]; | ||
40 | } | ||
41 | } | ||
42 | else { | ||
43 | delete array[toKey(index)]; | ||
44 | } | ||
45 | } | 32 | } |
46 | } | 33 | } |
47 | return array; | 34 | return array; |
@@ -1,5 +1,6 @@ | |||
1 | var baseGet = require('./_baseGet'), | 1 | var baseGet = require('./_baseGet'), |
2 | baseSet = require('./_baseSet'); | 2 | baseSet = require('./_baseSet'), |
3 | castPath = require('./_castPath'); | ||
3 | 4 | ||
4 | /** | 5 | /** |
5 | * The base implementation of `_.pickBy` without support for iteratee shorthands. | 6 | * The base implementation of `_.pickBy` without support for iteratee shorthands. |
@@ -20,7 +21,7 @@ | |||
20 | value = baseGet(object, path); | 21 | value = baseGet(object, path); |
21 | 22 | ||
22 | if (predicate(value, path)) { | 23 | if (predicate(value, path)) { |
23 | baseSet(result, path, value); | 24 | baseSet(result, castPath(path, object), value); |
24 | } | 25 | } |
25 | } | 26 | } |
26 | return result; | 27 | return result; |
@@ -11,7 +11,6 @@ | |||
11 | * @returns {Object} Returns the new object. | 11 | * @returns {Object} Returns the new object. |
12 | */ | 12 | */ |
13 | function basePick(object, paths) { | 13 | function basePick(object, paths) { |
14 | object = Object(object); | ||
15 | return basePickBy(object, paths, function(value, path) { | 14 | return basePickBy(object, paths, function(value, path) { |
16 | return hasIn(object, path); | 15 | return hasIn(object, path); |
17 | }); | 16 | }); |
@@ -1,6 +1,5 @@ | |||
1 | var castPath = require('./_castPath'), | 1 | var castPath = require('./_castPath'), |
2 | isFunction = require('./isFunction'), | 2 | isFunction = require('./isFunction'), |
3 | isKey = require('./_isKey'), | ||
4 | toKey = require('./_toKey'); | 3 | toKey = require('./_toKey'); |
5 | 4 | ||
6 | /** | 5 | /** |
@@ -33,15 +32,15 @@ | |||
33 | * // => 'default' | 32 | * // => 'default' |
34 | */ | 33 | */ |
35 | function result(object, path, defaultValue) { | 34 | function result(object, path, defaultValue) { |
36 | path = isKey(path, object) ? [path] : castPath(path); | 35 | path = castPath(path, object); |
37 | 36 | ||
38 | var index = -1, | 37 | var index = -1, |
39 | length = path.length; | 38 | length = path.length; |
40 | 39 | ||
41 | // Ensure the loop is entered when path is empty. | 40 | // Ensure the loop is entered when path is empty. |
42 | if (!length) { | 41 | if (!length) { |
42 | length = 1; | ||
43 | object = undefined; | 43 | object = undefined; |
44 | length = 1; | ||
45 | } | 44 | } |
46 | while (++index < length) { | 45 | while (++index < length) { |
47 | var value = object == null ? undefined : object[toKey(path[index])]; | 46 | var value = object == null ? undefined : object[toKey(path[index])]; |
@@ -11,6 +11,7 @@ | |||
11 | isObject = require('./isObject'), | 11 | isObject = require('./isObject'), |
12 | isPlainObject = require('./isPlainObject'), | 12 | isPlainObject = require('./isPlainObject'), |
13 | isTypedArray = require('./isTypedArray'), | 13 | isTypedArray = require('./isTypedArray'), |
14 | safeGet = require('./_safeGet'), | ||
14 | toPlainObject = require('./toPlainObject'); | 15 | toPlainObject = require('./toPlainObject'); |
15 | 16 | ||
16 | /** | 17 | /** |
@@ -29,8 +30,8 @@ | |||
29 | * counterparts. | 30 | * counterparts. |
30 | */ | 31 | */ |
31 | function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { | 32 | function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { |
32 | var objValue = object[key], | ||
33 | srcValue = source[key], | 33 | var objValue = safeGet(object, key), |
34 | srcValue = safeGet(source, key), | ||
34 | stacked = stack.get(srcValue); | 35 | stacked = stack.get(srcValue); |
35 | 36 | ||
36 | if (stacked) { | 37 | if (stacked) { |
@@ -73,7 +74,7 @@ | |||
73 | if (isArguments(objValue)) { | 74 | if (isArguments(objValue)) { |
74 | newValue = toPlainObject(objValue); | 75 | newValue = toPlainObject(objValue); |
75 | } | 76 | } |
76 | else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { | 77 | else if (!isObject(objValue) || isFunction(objValue)) { |
77 | newValue = initCloneObject(srcValue); | 78 | newValue = initCloneObject(srcValue); |
78 | } | 79 | } |
79 | } | 80 | } |
@@ -3,7 +3,8 @@ | |||
3 | baseFor = require('./_baseFor'), | 3 | baseFor = require('./_baseFor'), |
4 | baseMergeDeep = require('./_baseMergeDeep'), | 4 | baseMergeDeep = require('./_baseMergeDeep'), |
5 | isObject = require('./isObject'), | 5 | isObject = require('./isObject'), |
6 | keysIn = require('./keysIn'); | 6 | keysIn = require('./keysIn'), |
7 | safeGet = require('./_safeGet'); | ||
7 | 8 | ||
8 | /** | 9 | /** |
9 | * The base implementation of `_.merge` without support for multiple sources. | 10 | * The base implementation of `_.merge` without support for multiple sources. |
@@ -21,13 +22,13 @@ | |||
21 | return; | 22 | return; |
22 | } | 23 | } |
23 | baseFor(source, function(srcValue, key) { | 24 | baseFor(source, function(srcValue, key) { |
25 | stack || (stack = new Stack); | ||
24 | if (isObject(srcValue)) { | 26 | if (isObject(srcValue)) { |
25 | stack || (stack = new Stack); | ||
26 | baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); | 27 | baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); |
27 | } | 28 | } |
28 | else { | 29 | else { |
29 | var newValue = customizer | 30 | var newValue = customizer |
30 | ? customizer(object[key], srcValue, (key + ''), object, source, stack) | 31 | ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) |
31 | : undefined; | 32 | : undefined; |
32 | 33 | ||
33 | if (newValue === undefined) { | 34 | if (newValue === undefined) { |
@@ -38,17 +38,12 @@ | |||
38 | function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { | 38 | function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { |
39 | var objIsArr = isArray(object), | 39 | var objIsArr = isArray(object), |
40 | othIsArr = isArray(other), | 40 | othIsArr = isArray(other), |
41 | objTag = arrayTag, | ||
42 | othTag = arrayTag; | 41 | objTag = objIsArr ? arrayTag : getTag(object), |
42 | othTag = othIsArr ? arrayTag : getTag(other); | ||
43 | 43 | ||
44 | if (!objIsArr) { | ||
45 | objTag = getTag(object); | ||
46 | objTag = objTag == argsTag ? objectTag : objTag; | ||
47 | } | ||
48 | if (!othIsArr) { | ||
49 | othTag = getTag(other); | ||
50 | othTag = othTag == argsTag ? objectTag : othTag; | ||
51 | } | 44 | objTag = objTag == argsTag ? objectTag : objTag; |
45 | othTag = othTag == argsTag ? objectTag : othTag; | ||
46 | |||
52 | var objIsObj = objTag == objectTag, | 47 | var objIsObj = objTag == objectTag, |
53 | othIsObj = othTag == objectTag, | 48 | othIsObj = othTag == objectTag, |
54 | isSameTag = objTag == othTag; | 49 | isSameTag = objTag == othTag; |
@@ -1,5 +1,4 @@ | |||
1 | var baseIsEqualDeep = require('./_baseIsEqualDeep'), | 1 | var baseIsEqualDeep = require('./_baseIsEqualDeep'), |
2 | isObject = require('./isObject'), | ||
3 | isObjectLike = require('./isObjectLike'); | 2 | isObjectLike = require('./isObjectLike'); |
4 | 3 | ||
5 | /** | 4 | /** |
@@ -20,7 +19,7 @@ | |||
20 | if (value === other) { | 19 | if (value === other) { |
21 | return true; | 20 | return true; |
22 | } | 21 | } |
23 | if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { | 22 | if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { |
24 | return value !== value && other !== other; | 23 | return value !== value && other !== other; |
25 | } | 24 | } |
26 | return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); | 25 | return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); |
@@ -48,18 +48,14 @@ | |||
48 | if (typeof func != 'function') { | 48 | if (typeof func != 'function') { |
49 | throw new TypeError(FUNC_ERROR_TEXT); | 49 | throw new TypeError(FUNC_ERROR_TEXT); |
50 | } | 50 | } |
51 | start = start === undefined ? 0 : nativeMax(toInteger(start), 0); | 51 | start = start == null ? 0 : nativeMax(toInteger(start), 0); |
52 | return baseRest(function(args) { | 52 | return baseRest(function(args) { |
53 | var array = args[start], | 53 | var array = args[start], |
54 | lastIndex = args.length - 1, | ||
55 | otherArgs = castSlice(args, 0, start); | 54 | otherArgs = castSlice(args, 0, start); |
56 | 55 | ||
57 | if (array) { | 56 | if (array) { |
58 | arrayPush(otherArgs, array); | 57 | arrayPush(otherArgs, array); |
59 | } | 58 | } |
60 | if (start != lastIndex) { | ||
61 | arrayPush(otherArgs, castSlice(args, start + 1)); | ||
62 | } | ||
63 | return apply(func, this, otherArgs); | 59 | return apply(func, this, otherArgs); |
64 | }); | 60 | }); |
65 | } | 61 | } |
@@ -1,6 +1,5 @@ | |||
1 | var apply = require('./_apply'), | 1 | var apply = require('./_apply'), |
2 | castPath = require('./_castPath'), | 2 | castPath = require('./_castPath'), |
3 | isKey = require('./_isKey'), | ||
4 | last = require('./last'), | 3 | last = require('./last'), |
5 | parent = require('./_parent'), | 4 | parent = require('./_parent'), |
6 | toKey = require('./_toKey'); | 5 | toKey = require('./_toKey'); |
@@ -16,12 +15,9 @@ | |||
16 | * @returns {*} Returns the result of the invoked method. | 15 | * @returns {*} Returns the result of the invoked method. |
17 | */ | 16 | */ |
18 | function baseInvoke(object, path, args) { | 17 | function baseInvoke(object, path, args) { |
19 | if (!isKey(path, object)) { | ||
20 | path = castPath(path); | ||
21 | object = parent(object, path); | ||
22 | path = last(path); | ||
23 | } | ||
24 | var func = object == null ? object : object[toKey(path)]; | 18 | path = castPath(path, object); |
19 | object = parent(object, path); | ||
20 | var func = object == null ? object : object[toKey(last(path))]; | ||
25 | return func == null ? undefined : apply(func, object, args); | 21 | return func == null ? undefined : apply(func, object, args); |
26 | } | 22 | } |
27 | 23 |
@@ -28,7 +28,10 @@ | |||
28 | */ | 28 | */ |
29 | function startsWith(string, target, position) { | 29 | function startsWith(string, target, position) { |
30 | string = toString(string); | 30 | string = toString(string); |
31 | position = baseClamp(toInteger(position), 0, string.length); | 31 | position = position == null |
32 | ? 0 | ||
33 | : baseClamp(toInteger(position), 0, string.length); | ||
34 | |||
32 | target = baseToString(target); | 35 | target = baseToString(target); |
33 | return string.slice(position, position + target.length) == target; | 36 | return string.slice(position, position + target.length) == target; |
34 | } | 37 | } |
@@ -20,8 +20,7 @@ | |||
20 | if (value == null) { | 20 | if (value == null) { |
21 | return value === undefined ? undefinedTag : nullTag; | 21 | return value === undefined ? undefinedTag : nullTag; |
22 | } | 22 | } |
23 | value = Object(value); | ||
24 | return (symToStringTag && symToStringTag in value) | 23 | return (symToStringTag && symToStringTag in Object(value)) |
25 | ? getRawTag(value) | 24 | ? getRawTag(value) |
26 | : objectToString(value); | 25 | : objectToString(value); |
27 | } | 26 | } |
@@ -1,5 +1,4 @@ | |||
1 | var castPath = require('./_castPath'), | 1 | var castPath = require('./_castPath'), |
2 | isKey = require('./_isKey'), | ||
3 | toKey = require('./_toKey'); | 2 | toKey = require('./_toKey'); |
4 | 3 | ||
5 | /** | 4 | /** |
@@ -11,7 +10,7 @@ | |||
11 | * @returns {*} Returns the resolved value. | 10 | * @returns {*} Returns the resolved value. |
12 | */ | 11 | */ |
13 | function baseGet(object, path) { | 12 | function baseGet(object, path) { |
14 | path = isKey(path, object) ? [path] : castPath(path); | 13 | path = castPath(path, object); |
15 | 14 | ||
16 | var index = 0, | 15 | var index = 0, |
17 | length = path.length; | 16 | length = path.length; |
@@ -17,7 +17,7 @@ | |||
17 | * | 17 | * |
18 | * var users = [ | 18 | * var users = [ |
19 | * { 'user': 'barney', 'active': false }, | 19 | * { 'user': 'barney', 'active': false }, |
20 | * { 'user': 'fred', 'active': false}, | 20 | * { 'user': 'fred', 'active': false }, |
21 | * { 'user': 'pebbles', 'active': true } | 21 | * { 'user': 'pebbles', 'active': true } |
22 | * ]; | 22 | * ]; |
23 | * | 23 | * |
@@ -1,7 +1,7 @@ | |||
1 | var assignInDefaults = require('./_assignInDefaults'), | ||
2 | assignInWith = require('./assignInWith'), | 1 | var assignInWith = require('./assignInWith'), |
3 | attempt = require('./attempt'), | 2 | attempt = require('./attempt'), |
4 | baseValues = require('./_baseValues'), | 3 | baseValues = require('./_baseValues'), |
4 | customDefaultsAssignIn = require('./_customDefaultsAssignIn'), | ||
5 | escapeStringChar = require('./_escapeStringChar'), | 5 | escapeStringChar = require('./_escapeStringChar'), |
6 | isError = require('./isError'), | 6 | isError = require('./isError'), |
7 | isIterateeCall = require('./_isIterateeCall'), | 7 | isIterateeCall = require('./_isIterateeCall'), |
@@ -27,6 +27,12 @@ | |||
27 | /** Used to match unescaped characters in compiled string literals. */ | 27 | /** Used to match unescaped characters in compiled string literals. */ |
28 | var reUnescapedString = /['\n\r\u2028\u2029\\]/g; | 28 | var reUnescapedString = /['\n\r\u2028\u2029\\]/g; |
29 | 29 | ||
30 | /** Used for built-in method references. */ | ||
31 | var objectProto = Object.prototype; | ||
32 | |||
33 | /** Used to check objects for own properties. */ | ||
34 | var hasOwnProperty = objectProto.hasOwnProperty; | ||
35 | |||
30 | /** | 36 | /** |
31 | * Creates a compiled template function that can interpolate data properties | 37 | * Creates a compiled template function that can interpolate data properties |
32 | * in "interpolate" delimiters, HTML-escape interpolated data properties in | 38 | * in "interpolate" delimiters, HTML-escape interpolated data properties in |
@@ -141,9 +147,9 @@ | |||
141 | options = undefined; | 147 | options = undefined; |
142 | } | 148 | } |
143 | string = toString(string); | 149 | string = toString(string); |
144 | options = assignInWith({}, options, settings, assignInDefaults); | 150 | options = assignInWith({}, options, settings, customDefaultsAssignIn); |
145 | 151 | ||
146 | var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults), | 152 | var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn), |
147 | importsKeys = keys(imports), | 153 | importsKeys = keys(imports), |
148 | importsValues = baseValues(imports, importsKeys); | 154 | importsValues = baseValues(imports, importsKeys); |
149 | 155 | ||
@@ -162,7 +168,14 @@ | |||
162 | , 'g'); | 168 | , 'g'); |
163 | 169 | ||
164 | // Use a sourceURL for easier debugging. | 170 | // Use a sourceURL for easier debugging. |
165 | var sourceURL = 'sourceURL' in options ? '//# sourceURL=' + options.sourceURL + '\n' : ''; | 171 | // The sourceURL gets injected into the source that's eval-ed, so be careful |
172 | // with lookup (in case of e.g. prototype pollution), and strip newlines if any. | ||
173 | // A newline wouldn't be a valid sourceURL anyway, and it'd enable code injection. | ||
174 | var sourceURL = hasOwnProperty.call(options, 'sourceURL') | ||
175 | ? ('//# sourceURL=' + | ||
176 | (options.sourceURL + '').replace(/[\r\n]/g, ' ') + | ||
177 | '\n') | ||
178 | : ''; | ||
166 | 179 | ||
167 | string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) { | 180 | string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) { |
168 | interpolateValue || (interpolateValue = esTemplateValue); | 181 | interpolateValue || (interpolateValue = esTemplateValue); |
@@ -193,7 +206,9 @@ | |||
193 | 206 | ||
194 | // If `variable` is not specified wrap a with-statement around the generated | 207 | // If `variable` is not specified wrap a with-statement around the generated |
195 | // code to add the data object to the top of the scope chain. | 208 | // code to add the data object to the top of the scope chain. |
196 | var variable = options.variable; | 209 | // Like with sourceURL, we take care to not check the option's prototype, |
210 | // as this configuration is a code injection vector. | ||
211 | var variable = hasOwnProperty.call(options, 'variable') && options.variable; | ||
197 | if (!variable) { | 212 | if (!variable) { |
198 | source = 'with (obj) {\n' + source + '\n}\n'; | 213 | source = 'with (obj) {\n' + source + '\n}\n'; |
199 | } | 214 | } |
@@ -5,8 +5,8 @@ | |||
5 | 5 | ||
6 | /** | 6 | /** |
7 | * By default, the template delimiters used by lodash are like those in | 7 | * By default, the template delimiters used by lodash are like those in |
8 | * embedded Ruby (ERB). Change the following template settings to use | ||
9 | * alternative delimiters. | 8 | * embedded Ruby (ERB) as well as ES2015 template strings. Change the |
9 | * following template settings to use alternative delimiters. | ||
10 | * | 10 | * |
11 | * @static | 11 | * @static |
12 | * @memberOf _ | 12 | * @memberOf _ |
@@ -15,7 +15,9 @@ | |||
15 | initCloneObject = require('./_initCloneObject'), | 15 | initCloneObject = require('./_initCloneObject'), |
16 | isArray = require('./isArray'), | 16 | isArray = require('./isArray'), |
17 | isBuffer = require('./isBuffer'), | 17 | isBuffer = require('./isBuffer'), |
18 | isMap = require('./isMap'), | ||
18 | isObject = require('./isObject'), | 19 | isObject = require('./isObject'), |
20 | isSet = require('./isSet'), | ||
19 | keys = require('./keys'); | 21 | keys = require('./keys'); |
20 | 22 | ||
21 | /** Used to compose bitmasks for cloning. */ | 23 | /** Used to compose bitmasks for cloning. */ |
@@ -123,7 +125,7 @@ | |||
123 | if (!cloneableTags[tag]) { | 125 | if (!cloneableTags[tag]) { |
124 | return object ? value : {}; | 126 | return object ? value : {}; |
125 | } | 127 | } |
126 | result = initCloneByTag(value, tag, baseClone, isDeep); | 128 | result = initCloneByTag(value, tag, isDeep); |
127 | } | 129 | } |
128 | } | 130 | } |
129 | // Check for circular references and return its corresponding clone. | 131 | // Check for circular references and return its corresponding clone. |
@@ -134,6 +136,16 @@ | |||
134 | } | 136 | } |
135 | stack.set(value, result); | 137 | stack.set(value, result); |
136 | 138 | ||
139 | if (isSet(value)) { | ||
140 | value.forEach(function(subValue) { | ||
141 | result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); | ||
142 | }); | ||
143 | } else if (isMap(value)) { | ||
144 | value.forEach(function(subValue, key) { | ||
145 | result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); | ||
146 | }); | ||
147 | } | ||
148 | |||
137 | var keysFunc = isFull | 149 | var keysFunc = isFull |
138 | ? (isFlat ? getAllKeysIn : getAllKeys) | 150 | ? (isFlat ? getAllKeysIn : getAllKeys) |
139 | : (isFlat ? keysIn : keys); | 151 | : (isFlat ? keysIn : keys); |
@@ -3,7 +3,8 @@ | |||
3 | isArray = require('./isArray'), | 3 | isArray = require('./isArray'), |
4 | isSymbol = require('./isSymbol'), | 4 | isSymbol = require('./isSymbol'), |
5 | stringToPath = require('./_stringToPath'), | 5 | stringToPath = require('./_stringToPath'), |
6 | toKey = require('./_toKey'); | 6 | toKey = require('./_toKey'), |
7 | toString = require('./toString'); | ||
7 | 8 | ||
8 | /** | 9 | /** |
9 | * Converts `value` to a property path array. | 10 | * Converts `value` to a property path array. |
@@ -26,7 +27,7 @@ | |||
26 | if (isArray(value)) { | 27 | if (isArray(value)) { |
27 | return arrayMap(value, toKey); | 28 | return arrayMap(value, toKey); |
28 | } | 29 | } |
29 | return isSymbol(value) ? [value] : copyArray(stringToPath(value)); | 30 | return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value))); |
30 | } | 31 | } |
31 | 32 | ||
32 | module.exports = toPath; | 33 | module.exports = toPath; |
@@ -29,7 +29,9 @@ | |||
29 | * // => 3 | 29 | * // => 3 |
30 | */ | 30 | */ |
31 | function toSafeInteger(value) { | 31 | function toSafeInteger(value) { |
32 | return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER); | 32 | return value |
33 | ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) | ||
34 | : (value === 0 ? value : 0); | ||
33 | } | 35 | } |
34 | 36 | ||
35 | module.exports = toSafeInteger; | 37 | module.exports = toSafeInteger; |
@@ -29,9 +29,9 @@ | |||
29 | * Shortcut fusion is an optimization to merge iteratee calls; this avoids | 29 | * Shortcut fusion is an optimization to merge iteratee calls; this avoids |
30 | * the creation of intermediate arrays and can greatly reduce the number of | 30 | * the creation of intermediate arrays and can greatly reduce the number of |
31 | * iteratee executions. Sections of a chain sequence qualify for shortcut | 31 | * iteratee executions. Sections of a chain sequence qualify for shortcut |
32 | * fusion if the section is applied to an array of at least `200` elements | ||
33 | * and any iteratees accept only one argument. The heuristic for whether a | ||
34 | * section qualifies for shortcut fusion is subject to change. | 32 | * fusion if the section is applied to an array and iteratees accept only |
33 | * one argument. The heuristic for whether a section qualifies for shortcut | ||
34 | * fusion is subject to change. | ||
35 | * | 35 | * |
36 | * Chaining is supported in custom builds as long as the `_#value` method is | 36 | * Chaining is supported in custom builds as long as the `_#value` method is |
37 | * directly or indirectly included in the build. | 37 | * directly or indirectly included in the build. |
@@ -5,11 +5,12 @@ | |||
5 | 'curry': require('../curry'), | 5 | 'curry': require('../curry'), |
6 | 'forEach': require('../_arrayEach'), | 6 | 'forEach': require('../_arrayEach'), |
7 | 'isArray': require('../isArray'), | 7 | 'isArray': require('../isArray'), |
8 | 'isError': require('../isError'), | ||
8 | 'isFunction': require('../isFunction'), | 9 | 'isFunction': require('../isFunction'), |
10 | 'isWeakMap': require('../isWeakMap'), | ||
9 | 'iteratee': require('../iteratee'), | 11 | 'iteratee': require('../iteratee'), |
10 | 'keys': require('../_baseKeys'), | 12 | 'keys': require('../_baseKeys'), |
11 | 'rearg': require('../rearg'), | 13 | 'rearg': require('../rearg'), |
12 | 'spread': require('../spread'), | ||
13 | 'toInteger': require('../toInteger'), | 14 | 'toInteger': require('../toInteger'), |
14 | 'toPath': require('../toPath') | 15 | 'toPath': require('../toPath') |
15 | }; | 16 | }; |
@@ -167,7 +167,8 @@ | |||
167 | 167 | ||
168 | /** Used to map method names to iteratee rearg configs. */ | 168 | /** Used to map method names to iteratee rearg configs. */ |
169 | exports.iterateeRearg = { | 169 | exports.iterateeRearg = { |
170 | 'mapKeys': [1] | 170 | 'mapKeys': [1], |
171 | 'reduceRight': [1, 0] | ||
171 | }; | 172 | }; |
172 | 173 | ||
173 | /** Used to map method names to rearg configs. */ | 174 | /** Used to map method names to rearg configs. */ |
@@ -260,16 +261,6 @@ | |||
260 | } | 261 | } |
261 | }; | 262 | }; |
262 | 263 | ||
263 | /** Used to track methods with placeholder support */ | ||
264 | exports.placeholder = { | ||
265 | 'bind': true, | ||
266 | 'bindKey': true, | ||
267 | 'curry': true, | ||
268 | 'curryRight': true, | ||
269 | 'partial': true, | ||
270 | 'partialRight': true | ||
271 | }; | ||
272 | |||
273 | /** Used to map real names to their aliases. */ | 264 | /** Used to map real names to their aliases. */ |
274 | exports.realToAlias = (function() { | 265 | exports.realToAlias = (function() { |
275 | var hasOwnProperty = Object.prototype.hasOwnProperty, | 266 | var hasOwnProperty = Object.prototype.hasOwnProperty, |
@@ -0,0 +1,29 @@ | |
1 | var eq = require('./eq'); |
2 | |
3 | /** Used for built-in method references. */ |
4 | var objectProto = Object.prototype; |
5 | |
6 | /** Used to check objects for own properties. */ |
7 | var hasOwnProperty = objectProto.hasOwnProperty; |
8 | |
9 | /** |
10 | * Used by `_.defaults` to customize its `_.assignIn` use to assign properties |
11 | * of source objects to the destination object for all destination properties |
12 | * that resolve to `undefined`. |
13 | * |
14 | * @private |
15 | * @param {*} objValue The destination value. |
16 | * @param {*} srcValue The source value. |
17 | * @param {string} key The key of the property to assign. |
18 | * @param {Object} object The parent object of `objValue`. |
19 | * @returns {*} Returns the value to assign. |
20 | */ |
21 | function customDefaultsAssignIn(objValue, srcValue, key, object) { |
22 | if (objValue === undefined || |
23 | (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { |
24 | return srcValue; |
25 | } |
26 | return objValue; |
27 | } |
28 | |
29 | module.exports = customDefaultsAssignIn; |
@@ -0,0 +1,28 @@ | |
1 | var baseMerge = require('./_baseMerge'), |
2 | isObject = require('./isObject'); |
3 | |
4 | /** |
5 | * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source |
6 | * objects into destination objects that are passed thru. |
7 | * |
8 | * @private |
9 | * @param {*} objValue The destination value. |
10 | * @param {*} srcValue The source value. |
11 | * @param {string} key The key of the property to merge. |
12 | * @param {Object} object The parent object of `objValue`. |
13 | * @param {Object} source The parent object of `srcValue`. |
14 | * @param {Object} [stack] Tracks traversed source values and their merged |
15 | * counterparts. |
16 | * @returns {*} Returns the value to assign. |
17 | */ |
18 | function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { |
19 | if (isObject(objValue) && isObject(srcValue)) { |
20 | // Recursively merge objects and arrays (susceptible to call stack limits). |
21 | stack.set(srcValue, objValue); |
22 | baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); |
23 | stack['delete'](srcValue); |
24 | } |
25 | return objValue; |
26 | } |
27 | |
28 | module.exports = customDefaultsMerge; |