diff --git a/README.md b/README.md index fad914c1a..d06860546 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# lodash-es v4.16.3 +# lodash-es v4.16.4 The [Lodash](https://lodash.com/) library exported as [ES](http://www.ecma-international.org/ecma-262/6.0/) modules. @@ -7,4 +7,4 @@ Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli): $ lodash modularize exports=es -o ./ ``` -See the [package source](https://github.com/lodash/lodash/tree/4.16.3-es) for more details. +See the [package source](https://github.com/lodash/lodash/tree/4.16.4-es) for more details. diff --git a/_arrayLikeKeys.js b/_arrayLikeKeys.js index 387113d19..de5d55155 100644 --- a/_arrayLikeKeys.js +++ b/_arrayLikeKeys.js @@ -1,7 +1,9 @@ import baseTimes from './_baseTimes.js'; import isArguments from './isArguments.js'; import isArray from './isArray.js'; +import isBuffer from './isBuffer.js'; import isIndex from './_isIndex.js'; +import isTypedArray from './isTypedArray.js'; /** Used for built-in method references. */ var objectProto = Object.prototype; @@ -18,18 +20,26 @@ var hasOwnProperty = objectProto.hasOwnProperty; * @returns {Array} Returns the array of property names. */ function arrayLikeKeys(value, inherited) { - // Safari 8.1 makes `arguments.callee` enumerable in strict mode. - // Safari 9 makes `arguments.length` enumerable in strict mode. - var result = (isArray(value) || isArguments(value)) - ? baseTimes(value.length, String) - : []; - - var length = result.length, - skipIndexes = !!length; + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; for (var key in value) { if ((inherited || hasOwnProperty.call(value, key)) && - !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { result.push(key); } } diff --git a/_arraySampleSize.js b/_arraySampleSize.js index c361700f5..d5c9474b5 100644 --- a/_arraySampleSize.js +++ b/_arraySampleSize.js @@ -1,3 +1,4 @@ +import baseClamp from './_baseClamp.js'; import copyArray from './_copyArray.js'; import shuffleSelf from './_shuffleSelf.js'; @@ -10,7 +11,7 @@ import shuffleSelf from './_shuffleSelf.js'; * @returns {Array} Returns the random elements. */ function arraySampleSize(array, n) { - return shuffleSelf(copyArray(array), n); + return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length)); } export default arraySampleSize; diff --git a/_baseClone.js b/_baseClone.js index b2e134688..4fa9a4b72 100644 --- a/_baseClone.js +++ b/_baseClone.js @@ -118,9 +118,7 @@ function baseClone(value, isDeep, isFull, customizer, key, object, stack) { } stack.set(value, result); - if (!isArr) { - var props = isFull ? getAllKeys(value) : keys(value); - } + var props = isArr ? undefined : (isFull ? getAllKeys : keys)(value); arrayEach(props || value, function(subValue, key) { if (props) { key = subValue; diff --git a/_baseIsArguments.js b/_baseIsArguments.js new file mode 100644 index 000000000..f4ff1fc6f --- /dev/null +++ b/_baseIsArguments.js @@ -0,0 +1,27 @@ +import isObjectLike from './isObjectLike.js'; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ +function baseIsArguments(value) { + return isObjectLike(value) && objectToString.call(value) == argsTag; +} + +export default baseIsArguments; diff --git a/_baseMerge.js b/_baseMerge.js index e306a6274..37680f72f 100644 --- a/_baseMerge.js +++ b/_baseMerge.js @@ -1,11 +1,9 @@ import Stack from './_Stack.js'; -import arrayEach from './_arrayEach.js'; import assignMergeValue from './_assignMergeValue.js'; -import baseKeysIn from './_baseKeysIn.js'; +import baseFor from './_baseFor.js'; import baseMergeDeep from './_baseMergeDeep.js'; -import isArray from './isArray.js'; import isObject from './isObject.js'; -import isTypedArray from './isTypedArray.js'; +import keysIn from './keysIn.js'; /** * The base implementation of `_.merge` without support for multiple sources. @@ -22,14 +20,7 @@ function baseMerge(object, source, srcIndex, customizer, stack) { if (object === source) { return; } - if (!(isArray(source) || isTypedArray(source))) { - var props = baseKeysIn(source); - } - arrayEach(props || source, function(srcValue, key) { - if (props) { - key = srcValue; - srcValue = source[key]; - } + baseFor(source, function(srcValue, key) { if (isObject(srcValue)) { stack || (stack = new Stack); baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); @@ -44,7 +35,7 @@ function baseMerge(object, source, srcIndex, customizer, stack) { } assignMergeValue(object, key, newValue); } - }); + }, keysIn); } export default baseMerge; diff --git a/_baseMergeDeep.js b/_baseMergeDeep.js index 860ea19b9..a7962fbc7 100644 --- a/_baseMergeDeep.js +++ b/_baseMergeDeep.js @@ -1,10 +1,12 @@ import assignMergeValue from './_assignMergeValue.js'; +import cloneBuffer from './_cloneBuffer.js'; import cloneTypedArray from './_cloneTypedArray.js'; import copyArray from './_copyArray.js'; import initCloneObject from './_initCloneObject.js'; import isArguments from './isArguments.js'; import isArray from './isArray.js'; import isArrayLikeObject from './isArrayLikeObject.js'; +import isBuffer from './isBuffer.js'; import isFunction from './isFunction.js'; import isObject from './isObject.js'; import isPlainObject from './isPlainObject.js'; @@ -43,16 +45,21 @@ function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, sta if (isCommon) { var isArr = isArray(srcValue), - isTyped = !isArr && isTypedArray(srcValue); + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); newValue = srcValue; - if (isArr || isTyped) { + if (isArr || isBuff || isTyped) { if (isArray(objValue)) { newValue = objValue; } else if (isArrayLikeObject(objValue)) { newValue = copyArray(objValue); } + else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } else if (isTyped) { isCommon = false; newValue = cloneTypedArray(srcValue, true); diff --git a/_baseSampleSize.js b/_baseSampleSize.js index 7e2f32b12..04877a16b 100644 --- a/_baseSampleSize.js +++ b/_baseSampleSize.js @@ -1,3 +1,4 @@ +import baseClamp from './_baseClamp.js'; import shuffleSelf from './_shuffleSelf.js'; import values from './values.js'; @@ -10,7 +11,8 @@ import values from './values.js'; * @returns {Array} Returns the random elements. */ function baseSampleSize(collection, n) { - return shuffleSelf(values(collection), n); + var array = values(collection); + return shuffleSelf(array, baseClamp(n, 0, array.length)); } export default baseSampleSize; diff --git a/_baseToString.js b/_baseToString.js index 3b264fc60..7b5b35c58 100644 --- a/_baseToString.js +++ b/_baseToString.js @@ -1,4 +1,6 @@ import Symbol from './_Symbol.js'; +import arrayMap from './_arrayMap.js'; +import isArray from './isArray.js'; import isSymbol from './isSymbol.js'; /** Used as references for various `Number` constants. */ @@ -21,6 +23,10 @@ function baseToString(value) { if (typeof value == 'string') { return value; } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } if (isSymbol(value)) { return symbolToString ? symbolToString.call(value) : ''; } diff --git a/_shuffleSelf.js b/_shuffleSelf.js index 178c8b977..a04ebea15 100644 --- a/_shuffleSelf.js +++ b/_shuffleSelf.js @@ -1,4 +1,3 @@ -import baseClamp from './_baseClamp.js'; import baseRandom from './_baseRandom.js'; /** @@ -14,7 +13,7 @@ function shuffleSelf(array, size) { length = array.length, lastIndex = length - 1; - size = size === undefined ? length : baseClamp(size, 0, length); + size = size === undefined ? length : size; while (++index < size) { var rand = baseRandom(index, lastIndex), value = array[rand]; diff --git a/isArguments.js b/isArguments.js index c5650a56a..6c49fe578 100644 --- a/isArguments.js +++ b/isArguments.js @@ -1,7 +1,5 @@ -import isArrayLikeObject from './isArrayLikeObject.js'; - -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]'; +import baseIsArguments from './_baseIsArguments.js'; +import isObjectLike from './isObjectLike.js'; /** Used for built-in method references. */ var objectProto = Object.prototype; @@ -9,13 +7,6 @@ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var objectToString = objectProto.toString; - /** Built-in value references. */ var propertyIsEnumerable = objectProto.propertyIsEnumerable; @@ -37,10 +28,9 @@ var propertyIsEnumerable = objectProto.propertyIsEnumerable; * _.isArguments([1, 2, 3]); * // => false */ -function isArguments(value) { - // Safari 8.1 makes `arguments.callee` enumerable in strict mode. - return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && - (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); -} +var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); +}; export default isArguments; diff --git a/isEmpty.js b/isEmpty.js index 48176a256..9fbccd579 100644 --- a/isEmpty.js +++ b/isEmpty.js @@ -1,10 +1,11 @@ +import baseKeys from './_baseKeys.js'; import getTag from './_getTag.js'; import isArguments from './isArguments.js'; import isArray from './isArray.js'; import isArrayLike from './isArrayLike.js'; import isBuffer from './isBuffer.js'; import isPrototype from './_isPrototype.js'; -import nativeKeys from './_nativeKeys.js'; +import isTypedArray from './isTypedArray.js'; /** `Object#toString` result references. */ var mapTag = '[object Map]', @@ -51,8 +52,8 @@ var hasOwnProperty = objectProto.hasOwnProperty; */ function isEmpty(value) { if (isArrayLike(value) && - (isArray(value) || typeof value == 'string' || - typeof value.splice == 'function' || isBuffer(value) || isArguments(value))) { + (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || + isBuffer(value) || isTypedArray(value) || isArguments(value))) { return !value.length; } var tag = getTag(value); @@ -60,7 +61,7 @@ function isEmpty(value) { return !value.size; } if (isPrototype(value)) { - return !nativeKeys(value).length; + return !baseKeys(value).length; } for (var key in value) { if (hasOwnProperty.call(value, key)) { diff --git a/isFunction.js b/isFunction.js index 4f45e4d3d..f1a819b35 100644 --- a/isFunction.js +++ b/isFunction.js @@ -34,7 +34,7 @@ var objectToString = objectProto.toString; */ function isFunction(value) { // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 8-9 which returns 'object' for typed array and other constructors. + // in Safari 9 which returns 'object' for typed array and other constructors. var tag = isObject(value) ? objectToString.call(value) : ''; return tag == funcTag || tag == genTag || tag == proxyTag; } diff --git a/lodash.default.js b/lodash.default.js index 24de68ae3..995eca22f 100644 --- a/lodash.default.js +++ b/lodash.default.js @@ -45,7 +45,7 @@ import toInteger from './toInteger.js'; import lodash from './wrapperLodash.js'; /** Used as the semantic version number. */ -var VERSION = '4.16.3'; +var VERSION = '4.16.4'; /** Used to compose bitmasks for function metadata. */ var BIND_KEY_FLAG = 2; diff --git a/package.json b/package.json index 772f3179c..6a5e709f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lodash-es", - "version": "4.16.3", + "version": "4.16.4", "description": "Lodash exported as ES modules.", "keywords": "es6, modules, stdlib, util", "homepage": "https://lodash.com/custom-builds", diff --git a/toString.js b/toString.js index 3f0bc49d9..ecf9e5020 100644 --- a/toString.js +++ b/toString.js @@ -8,8 +8,8 @@ import baseToString from './_baseToString.js'; * @memberOf _ * @since 4.0.0 * @category Lang - * @param {*} value The value to process. - * @returns {string} Returns the string. + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. * @example * * _.toString(null); diff --git a/transform.js b/transform.js index 2ea561aad..d6f9456ca 100644 --- a/transform.js +++ b/transform.js @@ -4,6 +4,7 @@ import baseForOwn from './_baseForOwn.js'; import baseIteratee from './_baseIteratee.js'; import getPrototype from './_getPrototype.js'; import isArray from './isArray.js'; +import isBuffer from './isBuffer.js'; import isFunction from './isFunction.js'; import isObject from './isObject.js'; import isTypedArray from './isTypedArray.js'; @@ -39,22 +40,23 @@ import isTypedArray from './isTypedArray.js'; * // => { '1': ['a', 'c'], '2': ['b'] } */ function transform(object, iteratee, accumulator) { - var isArr = isArray(object) || isTypedArray(object); - iteratee = baseIteratee(iteratee, 4); + var isArr = isArray(object), + isArrLike = isArr || isBuffer(object) || isTypedArray(object); + iteratee = baseIteratee(iteratee, 4); if (accumulator == null) { - if (isArr || isObject(object)) { - var Ctor = object.constructor; - if (isArr) { - accumulator = isArray(object) ? new Ctor : []; - } else { - accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; - } - } else { + var Ctor = object && object.constructor; + if (isArrLike) { + accumulator = isArr ? new Ctor : []; + } + else if (isObject(object)) { + accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; + } + else { accumulator = {}; } } - (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { + (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) { return iteratee(accumulator, value, index, object); }); return accumulator;