From 30daf83737e095cb3c2fa869e31b10be0e73ca99 Mon Sep 17 00:00:00 2001 From: jdalton Date: Sun, 17 May 2015 22:50:59 -0700 Subject: [PATCH] Bump to v3.9.0. --- README.md | 4 +- array/intersection.js | 35 ++++++--------- array/zipWith.js | 4 +- chain/lodash.js | 41 +++++++++--------- collection/invoke.js | 4 +- collection/map.js | 2 +- collection/reduce.js | 2 +- date/now.js | 4 +- function/debounce.js | 13 +++--- function/memoize.js | 6 +-- function/throttle.js | 12 +++--- internal/SetCache.js | 6 +-- internal/arrayExtremum.js | 30 +++++++++++++ internal/arrayMax.js | 25 ----------- internal/arrayMin.js | 25 ----------- internal/assignWith.js | 11 +---- internal/baseAssign.js | 34 ++------------- internal/baseAt.js | 2 +- internal/baseCompareAscending.js | 19 ++++++--- internal/baseCreate.js | 11 +++-- internal/{extremumBy.js => baseExtremum.js} | 22 ++++------ internal/baseGet.js | 6 +-- internal/baseIsEqual.js | 10 +---- internal/baseIsEqualDeep.js | 8 ++-- internal/baseIsMatch.js | 47 +++++++++++---------- internal/baseMatches.js | 41 ++++++------------ internal/baseMatchesProperty.js | 12 +++--- internal/baseMerge.js | 17 ++------ internal/basePullAt.js | 2 +- internal/baseToString.js | 2 +- internal/binaryIndex.js | 4 +- internal/binaryIndexBy.js | 10 ++++- internal/bufferClone.js | 12 +++--- internal/charAtCallback.js | 12 ------ internal/createAssigner.js | 10 ++--- internal/createCache.js | 6 +-- internal/createCtorWrapper.js | 14 +++++- internal/createExtremum.js | 30 ++++++------- internal/createFlow.js | 17 ++++---- internal/createHybridWrapper.js | 17 ++++---- internal/equalArrays.js | 47 ++++++++++----------- internal/equalObjects.js | 37 +++++++--------- internal/getFuncName.js | 36 ++++++---------- internal/getMatchData.js | 21 +++++++++ internal/getNative.js | 16 +++++++ internal/getSymbols.js | 19 --------- internal/isIndex.js | 4 +- internal/isLength.js | 2 +- internal/metaMap.js | 4 +- internal/root.js | 2 +- internal/shimKeys.js | 5 +-- internal/toIterable.js | 2 +- internal/toObject.js | 2 +- internal/toPath.js | 2 +- lang.js | 10 +++++ lang/clone.js | 5 ++- lang/cloneDeep.js | 5 ++- lang/eq.js | 2 + lang/gt.js | 25 +++++++++++ lang/gte.js | 25 +++++++++++ lang/isArray.js | 4 +- lang/isEqual.js | 9 ++-- lang/isFinite.js | 4 +- lang/isFunction.js | 4 +- lang/isMatch.js | 33 ++------------- lang/isNative.js | 7 ++- lang/isObject.js | 2 +- lang/isPlainObject.js | 8 ++-- lang/lt.js | 25 +++++++++++ lang/lte.js | 25 +++++++++++ lodash.js | 9 +++- math/max.js | 4 +- math/min.js | 4 +- object/get.js | 2 +- object/has.js | 12 +++++- object/keys.js | 6 +-- object/keysIn.js | 3 +- object/pairs.js | 3 ++ object/transform.js | 2 +- package.json | 2 +- string/escape.js | 2 +- string/pad.js | 2 +- string/padLeft.js | 2 +- string/padRight.js | 2 +- string/trunc.js | 2 +- support.js | 45 +------------------- utility/matchesProperty.js | 6 +-- utility/mixin.js | 3 -- utility/times.js | 2 +- 89 files changed, 527 insertions(+), 567 deletions(-) create mode 100644 internal/arrayExtremum.js delete mode 100644 internal/arrayMax.js delete mode 100644 internal/arrayMin.js rename internal/{extremumBy.js => baseExtremum.js} (50%) delete mode 100644 internal/charAtCallback.js create mode 100644 internal/getMatchData.js create mode 100644 internal/getNative.js delete mode 100644 internal/getSymbols.js create mode 100644 lang/eq.js create mode 100644 lang/gt.js create mode 100644 lang/gte.js create mode 100644 lang/lt.js create mode 100644 lang/lte.js diff --git a/README.md b/README.md index 8ba235379..3ca546f63 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# lodash-es v3.8.0 +# lodash-es v3.9.0 The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash](https://lodash.com/) exported as [ES](https://people.mozilla.org/~jorendorff/es6-draft.html) modules. @@ -7,4 +7,4 @@ Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli): $ lodash modularize modern exports=es -o ./ ``` -See the [package source](https://github.com/lodash/lodash/tree/3.8.0-es) for more details. +See the [package source](https://github.com/lodash/lodash/tree/3.9.0-es) for more details. diff --git a/array/intersection.js b/array/intersection.js index 9175f6aae..68c384989 100644 --- a/array/intersection.js +++ b/array/intersection.js @@ -2,6 +2,7 @@ import baseIndexOf from '../internal/baseIndexOf'; import cacheIndexOf from '../internal/cacheIndexOf'; import createCache from '../internal/createCache'; import isArrayLike from '../internal/isArrayLike'; +import restParam from '../function/restParam'; /** * Creates an array of unique values in all provided arrays using @@ -17,27 +18,19 @@ import isArrayLike from '../internal/isArrayLike'; * _.intersection([1, 2], [4, 2], [2, 1]); * // => [2] */ -function intersection() { - var args = [], - argsIndex = -1, - argsLength = arguments.length, - caches = [], +var intersection = restParam(function(arrays) { + var othLength = arrays.length, + othIndex = othLength, + caches = Array(length), indexOf = baseIndexOf, isCommon = true, result = []; - while (++argsIndex < argsLength) { - var value = arguments[argsIndex]; - if (isArrayLike(value)) { - args.push(value); - caches.push((isCommon && value.length >= 120) ? createCache(argsIndex && value) : null); - } + while (othIndex--) { + var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; + caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; } - argsLength = args.length; - if (argsLength < 2) { - return result; - } - var array = args[0], + var array = arrays[0], index = -1, length = array ? array.length : 0, seen = caches[0]; @@ -46,10 +39,10 @@ function intersection() { while (++index < length) { value = array[index]; if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { - argsIndex = argsLength; - while (--argsIndex) { - var cache = caches[argsIndex]; - if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value, 0)) < 0) { + var othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { continue outer; } } @@ -60,6 +53,6 @@ function intersection() { } } return result; -} +}); export default intersection; diff --git a/array/zipWith.js b/array/zipWith.js index 8c12ba2cb..3823c7cca 100644 --- a/array/zipWith.js +++ b/array/zipWith.js @@ -20,8 +20,8 @@ import unzipWith from './unzipWith'; */ var zipWith = restParam(function(arrays) { var length = arrays.length, - iteratee = arrays[length - 2], - thisArg = arrays[length - 1]; + iteratee = length > 2 ? arrays[length - 2] : undefined, + thisArg = length > 1 ? arrays[length - 1] : undefined; if (length > 2 && typeof iteratee == 'function') { length -= 2; diff --git a/chain/lodash.js b/chain/lodash.js index 9be09bdaa..6988a29b9 100644 --- a/chain/lodash.js +++ b/chain/lodash.js @@ -50,30 +50,31 @@ var hasOwnProperty = objectProto.hasOwnProperty; * `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`, * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`, * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`, - * `keysIn`, `map`, `mapValues`, `matches`, `matchesProperty`, `memoize`, - * `merge`, `mixin`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, - * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, - * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `reverse`, - * `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`, `splice`, - * `spread`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, - * `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, `transform`, - * `union`, `uniq`, `unshift`, `unzip`, `values`, `valuesIn`, `where`, - * `without`, `wrap`, `xor`, `zip`, and `zipObject` + * `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, + * `memoize`, `merge`, `method`, `methodOf`, `mixin`, `negate`, `omit`, `once`, + * `pairs`, `partial`, `partialRight`, `partition`, `pick`, `plant`, `pluck`, + * `property`, `propertyOf`, `pull`, `pullAt`, `push`, `range`, `rearg`, + * `reject`, `remove`, `rest`, `restParam`, `reverse`, `set`, `shuffle`, + * `slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`, `splice`, `spread`, + * `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, + * `thru`, `times`, `toArray`, `toPlainObject`, `transform`, `union`, `uniq`, + * `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `where`, `without`, + * `wrap`, `xor`, `zip`, `zipObject`, `zipWith` * * The wrapper methods that are **not** chainable by default are: * `add`, `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`, * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, - * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`, - * `identity`, `includes`, `indexOf`, `inRange`, `isArguments`, `isArray`, - * `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite` - * `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, - * `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, - * `join`, `kebabCase`, `last`, `lastIndexOf`, `max`, `min`, `noConflict`, - * `noop`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, - * `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`, `shift`, `size`, - * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, `startsWith`, - * `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, `unescape`, - * `uniqueId`, `value`, and `words` + * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `get`, + * `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, `inRange`, `isArguments`, + * `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, + * `isFinite` `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, + * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, + * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lt`, `lte`, + * `max`, `min`, `noConflict`, `noop`, `now`, `pad`, `padLeft`, `padRight`, + * `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, + * `runInContext`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, + * `sortedLastIndex`, `startCase`, `startsWith`, `sum`, `template`, `trim`, + * `trimLeft`, `trimRight`, `trunc`, `unescape`, `uniqueId`, `value`, and `words` * * The wrapper method `sample` will return a wrapped value when `n` is provided, * otherwise an unwrapped value is returned. diff --git a/collection/invoke.js b/collection/invoke.js index 7e5121de8..b35e55789 100644 --- a/collection/invoke.js +++ b/collection/invoke.js @@ -5,7 +5,7 @@ import isKey from '../internal/isKey'; import restParam from '../function/restParam'; /** - * Invokes the method at `path` on each element in `collection`, returning + * Invokes the method at `path` of each element in `collection`, returning * an array of the results of each invoked method. Any additional arguments * are provided to each invoked method. If `methodName` is a function it is * invoked for, and `this` bound to, each element in `collection`. @@ -33,7 +33,7 @@ var invoke = restParam(function(collection, path, args) { result = isArrayLike(collection) ? Array(collection.length) : []; baseEach(collection, function(value) { - var func = isFunc ? path : (isProp && value != null && value[path]); + var func = isFunc ? path : ((isProp && value != null) ? value[path] : null); result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); }); return result; diff --git a/collection/map.js b/collection/map.js index 156b20d57..fb4bc37ff 100644 --- a/collection/map.js +++ b/collection/map.js @@ -19,7 +19,7 @@ import isArray from '../lang/isArray'; * callback returns `true` for elements that have the properties of the given * object, else `false`. * - * Many lodash methods are guarded to work as interatees for methods like + * Many lodash methods are guarded to work as iteratees for methods like * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. * * The guarded methods are: diff --git a/collection/reduce.js b/collection/reduce.js index fbf01eaa9..8c5750d6f 100644 --- a/collection/reduce.js +++ b/collection/reduce.js @@ -10,7 +10,7 @@ import createReduce from '../internal/createReduce'; * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: * (accumulator, value, index|key, collection). * - * Many lodash methods are guarded to work as interatees for methods like + * Many lodash methods are guarded to work as iteratees for methods like * `_.reduce`, `_.reduceRight`, and `_.transform`. * * The guarded methods are: diff --git a/date/now.js b/date/now.js index 84429c0c1..7c94a3021 100644 --- a/date/now.js +++ b/date/now.js @@ -1,7 +1,7 @@ -import isNative from '../lang/isNative'; +import getNative from '../internal/getNative'; /* Native method references for those with the same name as other `lodash` methods. */ -var nativeNow = isNative(nativeNow = Date.now) && nativeNow; +var nativeNow = getNative(Date, 'now'); /** * Gets the number of milliseconds that have elapsed since the Unix epoch diff --git a/function/debounce.js b/function/debounce.js index 7d0185b50..bbe23240a 100644 --- a/function/debounce.js +++ b/function/debounce.js @@ -8,12 +8,13 @@ var FUNC_ERROR_TEXT = 'Expected a function'; var nativeMax = Math.max; /** - * Creates a function that delays invoking `func` until after `wait` milliseconds - * have elapsed since the last time it was invoked. The created function comes - * with a `cancel` method to cancel delayed invocations. Provide an options - * object to indicate that `func` should be invoked on the leading and/or - * trailing edge of the `wait` timeout. Subsequent calls to the debounced - * function return the result of the last `func` invocation. + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. + * Subsequent calls to the debounced function return the result of the last + * `func` invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked * on the trailing edge of the timeout only if the the debounced function is diff --git a/function/memoize.js b/function/memoize.js index 5d1ff7b6d..4744473e9 100644 --- a/function/memoize.js +++ b/function/memoize.js @@ -60,14 +60,14 @@ function memoize(func, resolver) { } var memoized = function() { var args = arguments, - cache = memoized.cache, - key = resolver ? resolver.apply(this, args) : args[0]; + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; if (cache.has(key)) { return cache.get(key); } var result = func.apply(this, args); - cache.set(key, result); + memoized.cache = cache.set(key, result); return result; }; memoized.cache = new memoize.Cache; diff --git a/function/throttle.js b/function/throttle.js index b92a56346..cfbfa7fa1 100644 --- a/function/throttle.js +++ b/function/throttle.js @@ -12,12 +12,12 @@ var debounceOptions = { }; /** - * Creates a function that only invokes `func` at most once per every `wait` - * milliseconds. The created function comes with a `cancel` method to cancel - * delayed invocations. Provide an options object to indicate that `func` - * should be invoked on the leading and/or trailing edge of the `wait` timeout. - * Subsequent calls to the throttled function return the result of the last - * `func` call. + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed invocations. Provide an options object to indicate + * that `func` should be invoked on the leading and/or trailing edge of the + * `wait` timeout. Subsequent calls to the throttled function return the + * result of the last `func` call. * * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked * on the trailing edge of the timeout only if the the throttled function is diff --git a/internal/SetCache.js b/internal/SetCache.js index b43e828ea..016612116 100644 --- a/internal/SetCache.js +++ b/internal/SetCache.js @@ -1,12 +1,12 @@ import cachePush from './cachePush'; -import isNative from '../lang/isNative'; +import getNative from './getNative'; import root from './root'; /** Native method references. */ -var Set = isNative(Set = root.Set) && Set; +var Set = getNative(root, 'Set'); /* Native method references for those with the same name as other `lodash` methods. */ -var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate; +var nativeCreate = getNative(Object, 'create'); /** * diff --git a/internal/arrayExtremum.js b/internal/arrayExtremum.js new file mode 100644 index 000000000..6a9b12628 --- /dev/null +++ b/internal/arrayExtremum.js @@ -0,0 +1,30 @@ +/** + * A specialized version of `baseExtremum` for arrays whichs invokes `iteratee` + * with one argument: (value). + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {*} Returns the extremum value. + */ +function arrayExtremum(array, iteratee, comparator, exValue) { + var index = -1, + length = array.length, + computed = exValue, + result = computed; + + while (++index < length) { + var value = array[index], + current = +iteratee(value); + + if (comparator(current, computed)) { + computed = current; + result = value; + } + } + return result; +} + +export default arrayExtremum; diff --git a/internal/arrayMax.js b/internal/arrayMax.js deleted file mode 100644 index 2d7338553..000000000 --- a/internal/arrayMax.js +++ /dev/null @@ -1,25 +0,0 @@ -/** Used as references for `-Infinity` and `Infinity`. */ -var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY; - -/** - * A specialized version of `_.max` for arrays without support for iteratees. - * - * @private - * @param {Array} array The array to iterate over. - * @returns {*} Returns the maximum value. - */ -function arrayMax(array) { - var index = -1, - length = array.length, - result = NEGATIVE_INFINITY; - - while (++index < length) { - var value = array[index]; - if (value > result) { - result = value; - } - } - return result; -} - -export default arrayMax; diff --git a/internal/arrayMin.js b/internal/arrayMin.js deleted file mode 100644 index 0bc05de09..000000000 --- a/internal/arrayMin.js +++ /dev/null @@ -1,25 +0,0 @@ -/** Used as references for `-Infinity` and `Infinity`. */ -var POSITIVE_INFINITY = Number.POSITIVE_INFINITY; - -/** - * A specialized version of `_.min` for arrays without support for iteratees. - * - * @private - * @param {Array} array The array to iterate over. - * @returns {*} Returns the minimum value. - */ -function arrayMin(array) { - var index = -1, - length = array.length, - result = POSITIVE_INFINITY; - - while (++index < length) { - var value = array[index]; - if (value < result) { - result = value; - } - } - return result; -} - -export default arrayMin; diff --git a/internal/assignWith.js b/internal/assignWith.js index 4f4c5711b..9343e6f16 100644 --- a/internal/assignWith.js +++ b/internal/assignWith.js @@ -1,12 +1,5 @@ -import getSymbols from './getSymbols'; import keys from '../object/keys'; -/** Used for native method references. */ -var arrayProto = Array.prototype; - -/** Native method references. */ -var push = arrayProto.push; - /** * A specialized version of `_.assign` for customizing assigned values without * support for argument juggling, multiple sources, and `this` binding `customizer` @@ -19,10 +12,8 @@ var push = arrayProto.push; * @returns {Object} Returns `object`. */ function assignWith(object, source, customizer) { - var props = keys(source); - push.apply(props, getSymbols(source)); - var index = -1, + props = keys(source), length = props.length; while (++index < length) { diff --git a/internal/baseAssign.js b/internal/baseAssign.js index 14b9581c6..98aa91b09 100644 --- a/internal/baseAssign.js +++ b/internal/baseAssign.js @@ -1,34 +1,6 @@ import baseCopy from './baseCopy'; -import getSymbols from './getSymbols'; -import isNative from '../lang/isNative'; import keys from '../object/keys'; -/** Native method references. */ -var preventExtensions = isNative(preventExtensions = Object.preventExtensions) && preventExtensions; - -/** Used as `baseAssign`. */ -var nativeAssign = (function() { - // Avoid `Object.assign` in Firefox 34-37 which have an early implementation - // with a now defunct try/catch behavior. See https://bugzilla.mozilla.org/show_bug.cgi?id=1103344 - // for more details. - // - // Use `Object.preventExtensions` on a plain object instead of simply using - // `Object('x')` because Chrome and IE fail to throw an error when attempting - // to assign values to readonly indexes of strings. - var func = preventExtensions && isNative(func = Object.assign) && func; - try { - if (func) { - var object = preventExtensions({ '1': 0 }); - object[0] = 1; - } - } catch(e) { - // Only attempt in strict mode. - try { func(object, 'xo'); } catch(e) {} - return !object[1] && func; - } - return false; -}()); - /** * The base implementation of `_.assign` without support for argument juggling, * multiple sources, and `customizer` functions. @@ -38,10 +10,10 @@ var nativeAssign = (function() { * @param {Object} source The source object. * @returns {Object} Returns `object`. */ -var baseAssign = nativeAssign || function(object, source) { +function baseAssign(object, source) { return source == null ? object - : baseCopy(source, getSymbols(source), baseCopy(source, keys(source), object)); -}; + : baseCopy(source, keys(source), object); +} export default baseAssign; diff --git a/internal/baseAt.js b/internal/baseAt.js index 6e8064f12..dcc302831 100644 --- a/internal/baseAt.js +++ b/internal/baseAt.js @@ -14,7 +14,7 @@ function baseAt(collection, props) { var index = -1, isNil = collection == null, isArr = !isNil && isArrayLike(collection), - length = isArr && collection.length, + length = isArr ? collection.length : 0, propsLength = props.length, result = Array(propsLength); diff --git a/internal/baseCompareAscending.js b/internal/baseCompareAscending.js index 7f945d129..113811a1e 100644 --- a/internal/baseCompareAscending.js +++ b/internal/baseCompareAscending.js @@ -3,19 +3,28 @@ * sorts them in ascending order without guaranteeing a stable sort. * * @private - * @param {*} value The value to compare to `other`. - * @param {*} other The value to compare to `value`. + * @param {*} value The value to compare. + * @param {*} other The other value to compare. * @returns {number} Returns the sort order indicator for `value`. */ function baseCompareAscending(value, other) { if (value !== other) { - var valIsReflexive = value === value, + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, othIsReflexive = other === other; - if (value > other || !valIsReflexive || (value === undefined && othIsReflexive)) { + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { return 1; } - if (value < other || !othIsReflexive || (other === undefined && valIsReflexive)) { + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { return -1; } } diff --git a/internal/baseCreate.js b/internal/baseCreate.js index ad1c0c093..58e5bf32f 100644 --- a/internal/baseCreate.js +++ b/internal/baseCreate.js @@ -1,5 +1,4 @@ import isObject from '../lang/isObject'; -import root from './root'; /** * The base implementation of `_.create` without support for assigning @@ -10,14 +9,14 @@ import root from './root'; * @returns {Object} Returns the new object. */ var baseCreate = (function() { - function Object() {} + function object() {} return function(prototype) { if (isObject(prototype)) { - Object.prototype = prototype; - var result = new Object; - Object.prototype = null; + object.prototype = prototype; + var result = new object; + object.prototype = null; } - return result || root.Object(); + return result || {}; }; }()); diff --git a/internal/extremumBy.js b/internal/baseExtremum.js similarity index 50% rename from internal/extremumBy.js rename to internal/baseExtremum.js index 30b9cf408..e17dc3637 100644 --- a/internal/extremumBy.js +++ b/internal/baseExtremum.js @@ -1,30 +1,24 @@ import baseEach from './baseEach'; -/** Used as references for `-Infinity` and `Infinity`. */ -var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, - POSITIVE_INFINITY = Number.POSITIVE_INFINITY; - /** * Gets the extremum value of `collection` invoking `iteratee` for each value * in `collection` to generate the criterion by which the value is ranked. - * The `iteratee` is invoked with three arguments: (value, index, collection). + * The `iteratee` is invoked with three arguments: (value, index|key, collection). * * @private * @param {Array|Object|string} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. - * @param {boolean} [isMin] Specify returning the minimum, instead of the - * maximum, extremum value. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. * @returns {*} Returns the extremum value. */ -function extremumBy(collection, iteratee, isMin) { - var exValue = isMin ? POSITIVE_INFINITY : NEGATIVE_INFINITY, - computed = exValue, +function baseExtremum(collection, iteratee, comparator, exValue) { + var computed = exValue, result = computed; baseEach(collection, function(value, index, collection) { - var current = iteratee(value, index, collection); - if ((isMin ? (current < computed) : (current > computed)) || - (current === exValue && current === result)) { + var current = +iteratee(value, index, collection); + if (comparator(current, computed) || (current === exValue && current === result)) { computed = current; result = value; } @@ -32,4 +26,4 @@ function extremumBy(collection, iteratee, isMin) { return result; } -export default extremumBy; +export default baseExtremum; diff --git a/internal/baseGet.js b/internal/baseGet.js index 495e49e8b..8034d6db1 100644 --- a/internal/baseGet.js +++ b/internal/baseGet.js @@ -17,11 +17,11 @@ function baseGet(object, path, pathKey) { if (pathKey !== undefined && pathKey in toObject(object)) { path = [pathKey]; } - var index = -1, + var index = 0, length = path.length; - while (object != null && ++index < length) { - object = object[path[index]]; + while (object != null && index < length) { + object = object[path[index++]]; } return (index && index == length) ? object : undefined; } diff --git a/internal/baseIsEqual.js b/internal/baseIsEqual.js index ec6aaee74..8468a1e68 100644 --- a/internal/baseIsEqual.js +++ b/internal/baseIsEqual.js @@ -1,4 +1,5 @@ import baseIsEqualDeep from './baseIsEqualDeep'; +import isObject from '../lang/isObject'; /** * The base implementation of `_.isEqual` without support for `this` binding @@ -14,17 +15,10 @@ import baseIsEqualDeep from './baseIsEqualDeep'; * @returns {boolean} Returns `true` if the values are equivalent, else `false`. */ function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { - // Exit early for identical values. if (value === other) { return true; } - var valType = typeof value, - othType = typeof other; - - // Exit early for unlike primitive values. - if ((valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object') || - value == null || other == null) { - // Return `false` unless both values are `NaN`. + if (value == null || other == null || (!isObject(value) && !isObject(other))) { return value !== value && other !== other; } return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); diff --git a/internal/baseIsEqualDeep.js b/internal/baseIsEqualDeep.js index 3a9c06e46..27978627a 100644 --- a/internal/baseIsEqualDeep.js +++ b/internal/baseIsEqualDeep.js @@ -66,11 +66,11 @@ function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, return equalByTag(object, other, objTag); } if (!isLoose) { - var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - if (valWrapped || othWrapped) { - return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); + if (objIsWrapped || othIsWrapped) { + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); } } if (!isSameTag) { diff --git a/internal/baseIsMatch.js b/internal/baseIsMatch.js index 60d461575..a47a8d29d 100644 --- a/internal/baseIsMatch.js +++ b/internal/baseIsMatch.js @@ -1,4 +1,5 @@ import baseIsEqual from './baseIsEqual'; +import toObject from './toObject'; /** * The base implementation of `_.isMatch` without support for callback @@ -6,41 +7,43 @@ import baseIsEqual from './baseIsEqual'; * * @private * @param {Object} object The object to inspect. - * @param {Array} props The source property names to match. - * @param {Array} values The source values to match. - * @param {Array} strictCompareFlags Strict comparison flags for source values. + * @param {Array} matchData The propery names, values, and compare flags to match. * @param {Function} [customizer] The function to customize comparing objects. * @returns {boolean} Returns `true` if `object` is a match, else `false`. */ -function baseIsMatch(object, props, values, strictCompareFlags, customizer) { - var index = -1, - length = props.length, +function baseIsMatch(object, matchData, customizer) { + var index = matchData.length, + length = index, noCustomizer = !customizer; - while (++index < length) { - if ((noCustomizer && strictCompareFlags[index]) - ? values[index] !== object[props[index]] - : !(props[index] in object) + if (object == null) { + return !length; + } + object = toObject(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) ) { return false; } } - index = -1; while (++index < length) { - var key = props[index], + data = matchData[index]; + var key = data[0], objValue = object[key], - srcValue = values[index]; + srcValue = data[1]; - if (noCustomizer && strictCompareFlags[index]) { - var result = objValue !== undefined || (key in object); - } else { - result = customizer ? customizer(objValue, srcValue, key) : undefined; - if (result === undefined) { - result = baseIsEqual(srcValue, objValue, customizer, true); + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var result = customizer ? customizer(objValue, srcValue, key) : undefined; + if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { + return false; } - } - if (!result) { - return false; } } return true; diff --git a/internal/baseMatches.js b/internal/baseMatches.js index 87f40a81d..d7b108455 100644 --- a/internal/baseMatches.js +++ b/internal/baseMatches.js @@ -1,7 +1,5 @@ import baseIsMatch from './baseIsMatch'; -import constant from '../utility/constant'; -import isStrictComparable from './isStrictComparable'; -import keys from '../object/keys'; +import getMatchData from './getMatchData'; import toObject from './toObject'; /** @@ -12,35 +10,20 @@ import toObject from './toObject'; * @returns {Function} Returns the new function. */ function baseMatches(source) { - var props = keys(source), - length = props.length; + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + var key = matchData[0][0], + value = matchData[0][1]; - if (!length) { - return constant(true); - } - if (length == 1) { - var key = props[0], - value = source[key]; - - if (isStrictComparable(value)) { - return function(object) { - if (object == null) { - return false; - } - return object[key] === value && (value !== undefined || (key in toObject(object))); - }; - } - } - var values = Array(length), - strictCompareFlags = Array(length); - - while (length--) { - value = source[props[length]]; - values[length] = value; - strictCompareFlags[length] = isStrictComparable(value); + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && (value !== undefined || (key in toObject(object))); + }; } return function(object) { - return object != null && baseIsMatch(toObject(object), props, values, strictCompareFlags); + return baseIsMatch(object, matchData); }; } diff --git a/internal/baseMatchesProperty.js b/internal/baseMatchesProperty.js index 4cd67cfd3..9685d1e3f 100644 --- a/internal/baseMatchesProperty.js +++ b/internal/baseMatchesProperty.js @@ -14,12 +14,12 @@ import toPath from './toPath'; * * @private * @param {string} path The path of the property to get. - * @param {*} value The value to compare. + * @param {*} srcValue The value to compare. * @returns {Function} Returns the new function. */ -function baseMatchesProperty(path, value) { +function baseMatchesProperty(path, srcValue) { var isArr = isArray(path), - isCommon = isKey(path) && isStrictComparable(value), + isCommon = isKey(path) && isStrictComparable(srcValue), pathKey = (path + ''); path = toPath(path); @@ -37,9 +37,9 @@ function baseMatchesProperty(path, value) { key = last(path); object = toObject(object); } - return object[key] === value - ? (value !== undefined || (key in object)) - : baseIsEqual(value, object[key], null, true); + return object[key] === srcValue + ? (srcValue !== undefined || (key in object)) + : baseIsEqual(srcValue, object[key], undefined, true); }; } diff --git a/internal/baseMerge.js b/internal/baseMerge.js index caf73774d..233fa16ef 100644 --- a/internal/baseMerge.js +++ b/internal/baseMerge.js @@ -1,6 +1,5 @@ import arrayEach from './arrayEach'; import baseMergeDeep from './baseMergeDeep'; -import getSymbols from './getSymbols'; import isArray from '../lang/isArray'; import isArrayLike from './isArrayLike'; import isObject from '../lang/isObject'; @@ -8,12 +7,6 @@ import isObjectLike from './isObjectLike'; import isTypedArray from '../lang/isTypedArray'; import keys from '../object/keys'; -/** Used for native method references. */ -var arrayProto = Array.prototype; - -/** Native method references. */ -var push = arrayProto.push; - /** * The base implementation of `_.merge` without support for argument juggling, * multiple sources, and `this` binding `customizer` functions. @@ -30,11 +23,9 @@ function baseMerge(object, source, customizer, stackA, stackB) { if (!isObject(object)) { return object; } - var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)); - if (!isSrcArr) { - var props = keys(source); - push.apply(props, getSymbols(source)); - } + var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), + props = isSrcArr ? null : keys(source); + arrayEach(props || source, function(srcValue, key) { if (props) { key = srcValue; @@ -53,7 +44,7 @@ function baseMerge(object, source, customizer, stackA, stackB) { if (isCommon) { result = srcValue; } - if ((isSrcArr || result !== undefined) && + if ((result !== undefined || (isSrcArr && !(key in object))) && (isCommon || (result === result ? (result !== value) : (value === value)))) { object[key] = result; } diff --git a/internal/basePullAt.js b/internal/basePullAt.js index a4ea22d33..4cb090d57 100644 --- a/internal/basePullAt.js +++ b/internal/basePullAt.js @@ -18,7 +18,7 @@ var splice = arrayProto.splice; function basePullAt(array, indexes) { var length = array ? indexes.length : 0; while (length--) { - var index = parseFloat(indexes[length]); + var index = indexes[length]; if (index != previous && isIndex(index)) { var previous = index; splice.call(array, index, 1); diff --git a/internal/baseToString.js b/internal/baseToString.js index 25c63d356..4d5e22628 100644 --- a/internal/baseToString.js +++ b/internal/baseToString.js @@ -1,5 +1,5 @@ /** - * Converts `value` to a string if it is not one. An empty string is returned + * Converts `value` to a string if it's not one. An empty string is returned * for `null` or `undefined` values. * * @private diff --git a/internal/binaryIndex.js b/internal/binaryIndex.js index d67ec136c..37024e29d 100644 --- a/internal/binaryIndex.js +++ b/internal/binaryIndex.js @@ -2,7 +2,7 @@ import binaryIndexBy from './binaryIndexBy'; import identity from '../utility/identity'; /** Used as references for the maximum length and index of an array. */ -var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1, +var MAX_ARRAY_LENGTH = 4294967295, HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; /** @@ -25,7 +25,7 @@ function binaryIndex(array, value, retHighest) { var mid = (low + high) >>> 1, computed = array[mid]; - if (retHighest ? (computed <= value) : (computed < value)) { + if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { low = mid + 1; } else { high = mid; diff --git a/internal/binaryIndexBy.js b/internal/binaryIndexBy.js index 8e0cc1bca..f97e923f2 100644 --- a/internal/binaryIndexBy.js +++ b/internal/binaryIndexBy.js @@ -5,7 +5,7 @@ var floor = Math.floor; var nativeMin = Math.min; /** Used as references for the maximum length and index of an array. */ -var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1, +var MAX_ARRAY_LENGTH = 4294967295, MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; /** @@ -27,17 +27,23 @@ function binaryIndexBy(array, value, iteratee, retHighest) { var low = 0, high = array ? array.length : 0, valIsNaN = value !== value, + valIsNull = value === null, valIsUndef = value === undefined; while (low < high) { var mid = floor((low + high) / 2), computed = iteratee(array[mid]), + isDef = computed !== undefined, isReflexive = computed === computed; if (valIsNaN) { var setLow = isReflexive || retHighest; + } else if (valIsNull) { + setLow = isReflexive && isDef && (retHighest || computed != null); } else if (valIsUndef) { - setLow = isReflexive && (retHighest || computed !== undefined); + setLow = isReflexive && (retHighest || isDef); + } else if (computed == null) { + setLow = false; } else { setLow = retHighest ? (computed <= value) : (computed < value); } diff --git a/internal/bufferClone.js b/internal/bufferClone.js index b9b6321e9..2f80240f8 100644 --- a/internal/bufferClone.js +++ b/internal/bufferClone.js @@ -1,12 +1,12 @@ import constant from '../utility/constant'; -import isNative from '../lang/isNative'; +import getNative from './getNative'; import root from './root'; /** Native method references. */ -var ArrayBuffer = isNative(ArrayBuffer = root.ArrayBuffer) && ArrayBuffer, - bufferSlice = isNative(bufferSlice = ArrayBuffer && new ArrayBuffer(0).slice) && bufferSlice, +var ArrayBuffer = getNative(root, 'ArrayBuffer'), + bufferSlice = getNative(ArrayBuffer && new ArrayBuffer(0), 'slice'), floor = Math.floor, - Uint8Array = isNative(Uint8Array = root.Uint8Array) && Uint8Array; + Uint8Array = getNative(root, 'Uint8Array'); /** Used to clone array buffers. */ var Float64Array = (function() { @@ -14,10 +14,10 @@ var Float64Array = (function() { // where the array buffer's `byteLength` is not a multiple of the typed // array's `BYTES_PER_ELEMENT`. try { - var func = isNative(func = root.Float64Array) && func, + var func = getNative(root, 'Float64Array'), result = new func(new ArrayBuffer(10), 0, 1) && func; } catch(e) {} - return result; + return result || null; }()); /** Used as the size, in bytes, of each `Float64Array` element. */ diff --git a/internal/charAtCallback.js b/internal/charAtCallback.js deleted file mode 100644 index 9ff01d81c..000000000 --- a/internal/charAtCallback.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Used by `_.max` and `_.min` as the default callback for string values. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the code unit of the first character of the string. - */ -function charAtCallback(string) { - return string.charCodeAt(0); -} - -export default charAtCallback; diff --git a/internal/createAssigner.js b/internal/createAssigner.js index a1179b7f4..07658047a 100644 --- a/internal/createAssigner.js +++ b/internal/createAssigner.js @@ -16,19 +16,19 @@ function createAssigner(assigner) { return restParam(function(object, sources) { var index = -1, length = object == null ? 0 : sources.length, - customizer = length > 2 && sources[length - 2], - guard = length > 2 && sources[2], - thisArg = length > 1 && sources[length - 1]; + customizer = length > 2 ? sources[length - 2] : undefined, + guard = length > 2 ? sources[2] : undefined, + thisArg = length > 1 ? sources[length - 1] : undefined; if (typeof customizer == 'function') { customizer = bindCallback(customizer, thisArg, 5); length -= 2; } else { - customizer = typeof thisArg == 'function' ? thisArg : null; + customizer = typeof thisArg == 'function' ? thisArg : undefined; length -= (customizer ? 1 : 0); } if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? null : customizer; + customizer = length < 3 ? undefined : customizer; length = 1; } while (++index < length) { diff --git a/internal/createCache.js b/internal/createCache.js index 8f395da28..2143b9106 100644 --- a/internal/createCache.js +++ b/internal/createCache.js @@ -1,13 +1,13 @@ import SetCache from './SetCache'; import constant from '../utility/constant'; -import isNative from '../lang/isNative'; +import getNative from './getNative'; import root from './root'; /** Native method references. */ -var Set = isNative(Set = root.Set) && Set; +var Set = getNative(root, 'Set'); /* Native method references for those with the same name as other `lodash` methods. */ -var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate; +var nativeCreate = getNative(Object, 'create'); /** * Creates a `Set` cache object to optimize linear searches of large arrays. diff --git a/internal/createCtorWrapper.js b/internal/createCtorWrapper.js index 33ddcb010..27d2bd132 100644 --- a/internal/createCtorWrapper.js +++ b/internal/createCtorWrapper.js @@ -11,8 +11,20 @@ import isObject from '../lang/isObject'; */ function createCtorWrapper(Ctor) { return function() { + // Use a `switch` statement to work with class constructors. + // See https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + } var thisBinding = baseCreate(Ctor.prototype), - result = Ctor.apply(thisBinding, arguments); + result = Ctor.apply(thisBinding, args); // Mimic the constructor's `return` behavior. // See https://es5.github.io/#x13.2.2 for more details. diff --git a/internal/createExtremum.js b/internal/createExtremum.js index 41d1456ec..27bace9bc 100644 --- a/internal/createExtremum.js +++ b/internal/createExtremum.js @@ -1,37 +1,31 @@ +import arrayExtremum from './arrayExtremum'; import baseCallback from './baseCallback'; -import charAtCallback from './charAtCallback'; -import extremumBy from './extremumBy'; -import isArray from '../lang/isArray'; +import baseExtremum from './baseExtremum'; import isIterateeCall from './isIterateeCall'; -import isString from '../lang/isString'; import toIterable from './toIterable'; /** * Creates a `_.max` or `_.min` function. * * @private - * @param {Function} arrayFunc The function to get the extremum value from an array. - * @param {boolean} [isMin] Specify returning the minimum, instead of the maximum, - * extremum value. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. * @returns {Function} Returns the new extremum function. */ -function createExtremum(arrayFunc, isMin) { +function createExtremum(comparator, exValue) { return function(collection, iteratee, thisArg) { if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { iteratee = null; } - var noIteratee = iteratee == null; - - iteratee = noIteratee ? iteratee : baseCallback(iteratee, thisArg, 3); - if (noIteratee) { - var isArr = isArray(collection); - if (!isArr && isString(collection)) { - iteratee = charAtCallback; - } else { - return arrayFunc(isArr ? collection : toIterable(collection)); + iteratee = baseCallback(iteratee, thisArg, 3); + if (iteratee.length == 1) { + collection = toIterable(collection); + var result = arrayExtremum(collection, iteratee, comparator, exValue); + if (!(collection.length && result === exValue)) { + return result; } } - return extremumBy(collection, iteratee, isMin); + return baseExtremum(collection, iteratee, comparator, exValue); }; } diff --git a/internal/createFlow.js b/internal/createFlow.js index 9e3e47e7b..78a4c9fb3 100644 --- a/internal/createFlow.js +++ b/internal/createFlow.js @@ -22,11 +22,8 @@ var FUNC_ERROR_TEXT = 'Expected a function'; */ function createFlow(fromRight) { return function() { - var length = arguments.length; - if (!length) { - return function() { return arguments[0]; }; - } var wrapper, + length = arguments.length, index = fromRight ? length : -1, leftIndex = 0, funcs = Array(length); @@ -36,15 +33,17 @@ function createFlow(fromRight) { if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } - var funcName = wrapper ? '' : getFuncName(func); - wrapper = funcName == 'wrapper' ? new LodashWrapper([]) : wrapper; + if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { + wrapper = new LodashWrapper([]); + } } index = wrapper ? -1 : length; while (++index < length) { func = funcs[index]; - funcName = getFuncName(func); - var data = funcName == 'wrapper' ? getData(func) : null; + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : null; + if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); } else { @@ -57,7 +56,7 @@ function createFlow(fromRight) { return wrapper.plant(args[0]).value(); } var index = 0, - result = funcs[index].apply(this, args); + result = length ? funcs[index].apply(this, args) : args[0]; while (++index < length) { result = funcs[index].call(this, result); diff --git a/internal/createHybridWrapper.js b/internal/createHybridWrapper.js index 6eeeae026..d5e85a7d1 100644 --- a/internal/createHybridWrapper.js +++ b/internal/createHybridWrapper.js @@ -44,10 +44,8 @@ function createHybridWrapper(func, bitmask, thisArg, partials, holders, partials isBindKey = bitmask & BIND_KEY_FLAG, isCurry = bitmask & CURRY_FLAG, isCurryBound = bitmask & CURRY_BOUND_FLAG, - isCurryRight = bitmask & CURRY_RIGHT_FLAG; - - var Ctor = !isBindKey && createCtorWrapper(func), - key = func; + isCurryRight = bitmask & CURRY_RIGHT_FLAG, + Ctor = isBindKey ? null : createCtorWrapper(func); function wrapper() { // Avoid `arguments` object use disqualifying optimizations by @@ -94,17 +92,18 @@ function createHybridWrapper(func, bitmask, thisArg, partials, holders, partials return result; } } - var thisBinding = isBind ? thisArg : this; - if (isBindKey) { - func = thisBinding[key]; - } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + if (argPos) { args = reorder(args, argPos); } if (isAry && ary < args.length) { args.length = ary; } - var fn = (this && this !== root && this instanceof wrapper) ? (Ctor || createCtorWrapper(func)) : func; + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtorWrapper(func); + } return fn.apply(thisBinding, args); } return wrapper; diff --git a/internal/equalArrays.js b/internal/equalArrays.js index 58d8f6234..f94e2f3e4 100644 --- a/internal/equalArrays.js +++ b/internal/equalArrays.js @@ -1,3 +1,5 @@ +import arraySome from './arraySome'; + /** * A specialized version of `baseIsEqualDeep` for arrays with support for * partial deep comparisons. @@ -15,40 +17,35 @@ function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { var index = -1, arrLength = array.length, - othLength = other.length, - result = true; + othLength = other.length; if (arrLength != othLength && !(isLoose && othLength > arrLength)) { return false; } - // Deep compare the contents, ignoring non-numeric properties. - while (result && ++index < arrLength) { + // Ignore non-index properties. + while (++index < arrLength) { var arrValue = array[index], - othValue = other[index]; + othValue = other[index], + result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; - result = undefined; - if (customizer) { - result = isLoose - ? customizer(othValue, arrValue, index) - : customizer(arrValue, othValue, index); - } - if (result === undefined) { - // Recursively compare arrays (susceptible to call stack limits). - if (isLoose) { - var othIndex = othLength; - while (othIndex--) { - othValue = other[othIndex]; - result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); - if (result) { - break; - } - } - } else { - result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + if (result !== undefined) { + if (result) { + continue; } + return false; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isLoose) { + if (!arraySome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + })) { + return false; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { + return false; } } - return !!result; + return true; } export default equalArrays; diff --git a/internal/equalObjects.js b/internal/equalObjects.js index 0aecfeaa8..cbae5d662 100644 --- a/internal/equalObjects.js +++ b/internal/equalObjects.js @@ -29,29 +29,22 @@ function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, sta if (objLength != othLength && !isLoose) { return false; } - var skipCtor = isLoose, - index = -1; - - while (++index < objLength) { - var key = objProps[index], - result = isLoose ? key in other : hasOwnProperty.call(other, key); - - if (result) { - var objValue = object[key], - othValue = other[key]; - - result = undefined; - if (customizer) { - result = isLoose - ? customizer(othValue, objValue, key) - : customizer(objValue, othValue, key); - } - if (result === undefined) { - // Recursively compare objects (susceptible to call stack limits). - result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB); - } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { + return false; } - if (!result) { + } + var skipCtor = isLoose; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key], + result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; + + // Recursively compare objects (susceptible to call stack limits). + if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { return false; } skipCtor || (skipCtor = key == 'constructor'); diff --git a/internal/getFuncName.js b/internal/getFuncName.js index 2c933cdb8..8b69fc83c 100644 --- a/internal/getFuncName.js +++ b/internal/getFuncName.js @@ -1,7 +1,4 @@ -import baseProperty from './baseProperty'; -import constant from '../utility/constant'; import realNames from './realNames'; -import support from '../support'; /** * Gets the name of `func`. @@ -10,28 +7,19 @@ import support from '../support'; * @param {Function} func The function to query. * @returns {string} Returns the function name. */ -var getFuncName = (function() { - if (!support.funcNames) { - return constant(''); - } - if (constant.name == 'constant') { - return baseProperty('name'); - } - return function(func) { - var result = func.name, - array = realNames[result], - length = array ? array.length : 0; +function getFuncName(func) { + var result = func.name, + array = realNames[result], + length = array ? array.length : 0; - while (length--) { - var data = array[length], - otherFunc = data.func; - - if (otherFunc == null || otherFunc == func) { - return data.name; - } + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; } - return result; - }; -}()); + } + return result; +} export default getFuncName; diff --git a/internal/getMatchData.js b/internal/getMatchData.js new file mode 100644 index 000000000..bccf3c31e --- /dev/null +++ b/internal/getMatchData.js @@ -0,0 +1,21 @@ +import isStrictComparable from './isStrictComparable'; +import pairs from '../object/pairs'; + +/** + * Gets the propery names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = pairs(object), + length = result.length; + + while (length--) { + result[length][2] = isStrictComparable(result[length][1]); + } + return result; +} + +export default getMatchData; diff --git a/internal/getNative.js b/internal/getNative.js new file mode 100644 index 000000000..099a9b379 --- /dev/null +++ b/internal/getNative.js @@ -0,0 +1,16 @@ +import isNative from '../lang/isNative'; + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = object == null ? undefined : object[key]; + return isNative(value) ? value : undefined; +} + +export default getNative; diff --git a/internal/getSymbols.js b/internal/getSymbols.js deleted file mode 100644 index e92386712..000000000 --- a/internal/getSymbols.js +++ /dev/null @@ -1,19 +0,0 @@ -import constant from '../utility/constant'; -import isNative from '../lang/isNative'; -import toObject from './toObject'; - -/** Native method references. */ -var getOwnPropertySymbols = isNative(getOwnPropertySymbols = Object.getOwnPropertySymbols) && getOwnPropertySymbols; - -/** - * Creates an array of the own symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ -var getSymbols = !getOwnPropertySymbols ? constant([]) : function(object) { - return getOwnPropertySymbols(toObject(object)); -}; - -export default getSymbols; diff --git a/internal/isIndex.js b/internal/isIndex.js index 7005f834e..73e34d32c 100644 --- a/internal/isIndex.js +++ b/internal/isIndex.js @@ -2,7 +2,7 @@ * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) * of an array-like value. */ -var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; +var MAX_SAFE_INTEGER = 9007199254740991; /** * Checks if `value` is a valid array-like index. @@ -13,7 +13,7 @@ var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ function isIndex(value, length) { - value = +value; + value = typeof value == 'number' ? value : parseFloat(value); length = length == null ? MAX_SAFE_INTEGER : length; return value > -1 && value % 1 == 0 && value < length; } diff --git a/internal/isLength.js b/internal/isLength.js index df747f68c..7ad9093f0 100644 --- a/internal/isLength.js +++ b/internal/isLength.js @@ -2,7 +2,7 @@ * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) * of an array-like value. */ -var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; +var MAX_SAFE_INTEGER = 9007199254740991; /** * Checks if `value` is a valid array-like length. diff --git a/internal/metaMap.js b/internal/metaMap.js index 3f37f644f..0b1d71119 100644 --- a/internal/metaMap.js +++ b/internal/metaMap.js @@ -1,8 +1,8 @@ -import isNative from '../lang/isNative'; +import getNative from './getNative'; import root from './root'; /** Native method references. */ -var WeakMap = isNative(WeakMap = root.WeakMap) && WeakMap; +var WeakMap = getNative(root, 'WeakMap'); /** Used to store function metadata. */ var metaMap = WeakMap && new WeakMap; diff --git a/internal/root.js b/internal/root.js index 51ef8c247..20d53b67d 100644 --- a/internal/root.js +++ b/internal/root.js @@ -22,7 +22,7 @@ var freeWindow = objectTypes[typeof window] && window && window.Object && window /** * Used as a reference to the global object. * - * The `this` value is used if it is the global object to avoid Greasemonkey's + * The `this` value is used if it's the global object to avoid Greasemonkey's * restricted `window` object, otherwise the `window` object is used. */ var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; diff --git a/internal/shimKeys.js b/internal/shimKeys.js index d4c91d338..fd7351231 100644 --- a/internal/shimKeys.js +++ b/internal/shimKeys.js @@ -3,7 +3,6 @@ import isArray from '../lang/isArray'; import isIndex from './isIndex'; import isLength from './isLength'; import keysIn from '../object/keysIn'; -import support from '../support'; /** Used for native method references. */ var objectProto = Object.prototype; @@ -24,8 +23,8 @@ function shimKeys(object) { propsLength = props.length, length = propsLength && object.length; - var allowIndexes = length && isLength(length) && - (isArray(object) || (support.nonEnumArgs && isArguments(object))); + var allowIndexes = !!length && isLength(length) && + (isArray(object) || isArguments(object)); var index = -1, result = []; diff --git a/internal/toIterable.js b/internal/toIterable.js index 908662599..dcce3cf9c 100644 --- a/internal/toIterable.js +++ b/internal/toIterable.js @@ -3,7 +3,7 @@ import isObject from '../lang/isObject'; import values from '../object/values'; /** - * Converts `value` to an array-like object if it is not one. + * Converts `value` to an array-like object if it's not one. * * @private * @param {*} value The value to process. diff --git a/internal/toObject.js b/internal/toObject.js index 93601057b..fa7de0eb9 100644 --- a/internal/toObject.js +++ b/internal/toObject.js @@ -1,7 +1,7 @@ import isObject from '../lang/isObject'; /** - * Converts `value` to an object if it is not one. + * Converts `value` to an object if it's not one. * * @private * @param {*} value The value to process. diff --git a/internal/toPath.js b/internal/toPath.js index 8c1da9306..918a521f5 100644 --- a/internal/toPath.js +++ b/internal/toPath.js @@ -8,7 +8,7 @@ var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*? var reEscapeChar = /\\(\\)?/g; /** - * Converts `value` to property path array if it is not one. + * Converts `value` to property path array if it's not one. * * @private * @param {*} value The value to process. diff --git a/lang.js b/lang.js index 2a7709748..3d281a2c0 100644 --- a/lang.js +++ b/lang.js @@ -1,5 +1,8 @@ import clone from './lang/clone'; import cloneDeep from './lang/cloneDeep'; +import eq from './lang/eq'; +import gt from './lang/gt'; +import gte from './lang/gte'; import isArguments from './lang/isArguments'; import isArray from './lang/isArray'; import isBoolean from './lang/isBoolean'; @@ -21,12 +24,17 @@ import isRegExp from './lang/isRegExp'; import isString from './lang/isString'; import isTypedArray from './lang/isTypedArray'; import isUndefined from './lang/isUndefined'; +import lt from './lang/lt'; +import lte from './lang/lte'; import toArray from './lang/toArray'; import toPlainObject from './lang/toPlainObject'; export default { 'clone': clone, 'cloneDeep': cloneDeep, + 'eq': eq, + 'gt': gt, + 'gte': gte, 'isArguments': isArguments, 'isArray': isArray, 'isBoolean': isBoolean, @@ -48,6 +56,8 @@ export default { 'isString': isString, 'isTypedArray': isTypedArray, 'isUndefined': isUndefined, + 'lt': lt, + 'lte': lte, 'toArray': toArray, 'toPlainObject': toPlainObject }; diff --git a/lang/clone.js b/lang/clone.js index ac51d7f40..3e4c5787b 100644 --- a/lang/clone.js +++ b/lang/clone.js @@ -62,8 +62,9 @@ function clone(value, isDeep, customizer, thisArg) { customizer = isDeep; isDeep = false; } - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1); - return baseClone(value, isDeep, customizer); + return typeof customizer == 'function' + ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 1)) + : baseClone(value, isDeep); } export default clone; diff --git a/lang/cloneDeep.js b/lang/cloneDeep.js index f1a355f5d..ff7e5d412 100644 --- a/lang/cloneDeep.js +++ b/lang/cloneDeep.js @@ -47,8 +47,9 @@ import bindCallback from '../internal/bindCallback'; * // => 20 */ function cloneDeep(value, customizer, thisArg) { - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1); - return baseClone(value, true, customizer); + return typeof customizer == 'function' + ? baseClone(value, true, bindCallback(customizer, thisArg, 1)) + : baseClone(value, true); } export default cloneDeep; diff --git a/lang/eq.js b/lang/eq.js new file mode 100644 index 000000000..fc0698220 --- /dev/null +++ b/lang/eq.js @@ -0,0 +1,2 @@ +import isEqual from './isEqual' +export default isEqual; diff --git a/lang/gt.js b/lang/gt.js new file mode 100644 index 000000000..7d3c725cf --- /dev/null +++ b/lang/gt.js @@ -0,0 +1,25 @@ +/** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ +function gt(value, other) { + return value > other; +} + +export default gt; diff --git a/lang/gte.js b/lang/gte.js new file mode 100644 index 000000000..e87108ecd --- /dev/null +++ b/lang/gte.js @@ -0,0 +1,25 @@ +/** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ +function gte(value, other) { + return value >= other; +} + +export default gte; diff --git a/lang/isArray.js b/lang/isArray.js index 4c916f47d..ecccce6a2 100644 --- a/lang/isArray.js +++ b/lang/isArray.js @@ -1,5 +1,5 @@ +import getNative from '../internal/getNative'; import isLength from '../internal/isLength'; -import isNative from './isNative'; import isObjectLike from '../internal/isObjectLike'; /** `Object#toString` result references. */ @@ -15,7 +15,7 @@ var objectProto = Object.prototype; var objToString = objectProto.toString; /* Native method references for those with the same name as other `lodash` methods. */ -var nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray; +var nativeIsArray = getNative(Array, 'isArray'); /** * Checks if `value` is classified as an `Array` object. diff --git a/lang/isEqual.js b/lang/isEqual.js index f38adcb01..e917b1f9c 100644 --- a/lang/isEqual.js +++ b/lang/isEqual.js @@ -1,6 +1,5 @@ import baseIsEqual from '../internal/baseIsEqual'; import bindCallback from '../internal/bindCallback'; -import isStrictComparable from '../internal/isStrictComparable'; /** * Performs a deep comparison between two values to determine if they are @@ -17,6 +16,7 @@ import isStrictComparable from '../internal/isStrictComparable'; * * @static * @memberOf _ + * @alias eq * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. @@ -46,12 +46,9 @@ import isStrictComparable from '../internal/isStrictComparable'; * // => true */ function isEqual(value, other, customizer, thisArg) { - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); - if (!customizer && isStrictComparable(value) && isStrictComparable(other)) { - return value === other; - } + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; var result = customizer ? customizer(value, other) : undefined; - return result === undefined ? baseIsEqual(value, other, customizer) : !!result; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; } export default isEqual; diff --git a/lang/isFinite.js b/lang/isFinite.js index 5bd7f679e..88a0d9be1 100644 --- a/lang/isFinite.js +++ b/lang/isFinite.js @@ -1,9 +1,9 @@ -import isNative from './isNative'; +import getNative from '../internal/getNative'; import root from '../internal/root'; /* Native method references for those with the same name as other `lodash` methods. */ var nativeIsFinite = root.isFinite, - nativeNumIsFinite = isNative(nativeNumIsFinite = Number.isFinite) && nativeNumIsFinite; + nativeNumIsFinite = getNative(Number, 'isFinite'); /** * Checks if `value` is a finite primitive number. diff --git a/lang/isFunction.js b/lang/isFunction.js index 5af802afb..a2eac06b4 100644 --- a/lang/isFunction.js +++ b/lang/isFunction.js @@ -1,5 +1,5 @@ import baseIsFunction from '../internal/baseIsFunction'; -import isNative from './isNative'; +import getNative from '../internal/getNative'; import root from '../internal/root'; /** `Object#toString` result references. */ @@ -15,7 +15,7 @@ var objectProto = Object.prototype; var objToString = objectProto.toString; /** Native method references. */ -var Uint8Array = isNative(Uint8Array = root.Uint8Array) && Uint8Array; +var Uint8Array = getNative(root, 'Uint8Array'); /** * Checks if `value` is classified as a `Function` object. diff --git a/lang/isMatch.js b/lang/isMatch.js index 37f932399..3d04d559a 100644 --- a/lang/isMatch.js +++ b/lang/isMatch.js @@ -1,8 +1,6 @@ import baseIsMatch from '../internal/baseIsMatch'; import bindCallback from '../internal/bindCallback'; -import isStrictComparable from '../internal/isStrictComparable'; -import keys from '../object/keys'; -import toObject from '../internal/toObject'; +import getMatchData from '../internal/getMatchData'; /** * Performs a deep comparison between `object` and `source` to determine if @@ -44,33 +42,8 @@ import toObject from '../internal/toObject'; * // => true */ function isMatch(object, source, customizer, thisArg) { - var props = keys(source), - length = props.length; - - if (!length) { - return true; - } - if (object == null) { - return false; - } - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); - object = toObject(object); - if (!customizer && length == 1) { - var key = props[0], - value = source[key]; - - if (isStrictComparable(value)) { - return value === object[key] && (value !== undefined || (key in object)); - } - } - var values = Array(length), - strictCompareFlags = Array(length); - - while (length--) { - value = values[length] = source[props[length]]; - strictCompareFlags[length] = isStrictComparable(value); - } - return baseIsMatch(object, props, values, strictCompareFlags, customizer); + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + return baseIsMatch(object, getMatchData(source), customizer); } export default isMatch; diff --git a/lang/isNative.js b/lang/isNative.js index 11d343a14..65cc534bb 100644 --- a/lang/isNative.js +++ b/lang/isNative.js @@ -13,6 +13,9 @@ var objectProto = Object.prototype; /** Used to resolve the decompiled source of functions. */ var fnToString = Function.prototype.toString; +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + /** * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) * of values. @@ -21,8 +24,8 @@ var objToString = objectProto.toString; /** Used to detect if a method is native. */ var reIsNative = RegExp('^' + - escapeRegExp(objToString) - .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + escapeRegExp(fnToString.call(hasOwnProperty)) + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); /** diff --git a/lang/isObject.js b/lang/isObject.js index d1187afee..19bba5e4a 100644 --- a/lang/isObject.js +++ b/lang/isObject.js @@ -22,7 +22,7 @@ function isObject(value) { // Avoid a V8 JIT bug in Chrome 19-20. // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. var type = typeof value; - return type == 'function' || (!!value && type == 'object'); + return !!value && (type == 'object' || type == 'function'); } export default isObject; diff --git a/lang/isPlainObject.js b/lang/isPlainObject.js index 43225beda..5176145a4 100644 --- a/lang/isPlainObject.js +++ b/lang/isPlainObject.js @@ -1,4 +1,4 @@ -import isNative from './isNative'; +import getNative from '../internal/getNative'; import shimIsPlainObject from '../internal/shimIsPlainObject'; /** `Object#toString` result references. */ @@ -14,7 +14,7 @@ var objectProto = Object.prototype; var objToString = objectProto.toString; /** Native method references. */ -var getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf; +var getPrototypeOf = getNative(Object, 'getPrototypeOf'); /** * Checks if `value` is a plain object, that is, an object created by the @@ -50,8 +50,8 @@ var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { if (!(value && objToString.call(value) == objectTag)) { return false; } - var valueOf = value.valueOf, - objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + var valueOf = getNative(value, 'valueOf'), + objProto = valueOf && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); return objProto ? (value == objProto || getPrototypeOf(value) == objProto) diff --git a/lang/lt.js b/lang/lt.js new file mode 100644 index 000000000..2cbfc2adc --- /dev/null +++ b/lang/lt.js @@ -0,0 +1,25 @@ +/** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ +function lt(value, other) { + return value < other; +} + +export default lt; diff --git a/lang/lte.js b/lang/lte.js new file mode 100644 index 000000000..2b8cb24b6 --- /dev/null +++ b/lang/lte.js @@ -0,0 +1,25 @@ +/** + * Checks if `value` is less than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`. + * @example + * + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false + */ +function lte(value, other) { + return value <= other; +} + +export default lte; diff --git a/lodash.js b/lodash.js index 08dacbd4c..642a5bb83 100644 --- a/lodash.js +++ b/lodash.js @@ -1,6 +1,6 @@ /** * @license - * lodash 3.8.0 (Custom Build) + * lodash 3.9.0 (Custom Build) * Build: `lodash modularize modern exports="es" -o ./` * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.8.3 @@ -42,7 +42,7 @@ import support from './support'; import thru from './chain/thru'; /** Used as the semantic version number. */ -var VERSION = '3.8.0'; +var VERSION = '3.9.0'; /** Used to compose bitmasks for wrapper metadata. */ var BIND_KEY_FLAG = 2; @@ -228,6 +228,8 @@ lodash.findLastKey = object.findLastKey; lodash.findWhere = collection.findWhere; lodash.first = array.first; lodash.get = object.get; +lodash.gt = lang.gt; +lodash.gte = lang.gte; lodash.has = object.has; lodash.identity = identity; lodash.includes = collection.includes; @@ -257,6 +259,8 @@ lodash.isUndefined = lang.isUndefined; lodash.kebabCase = string.kebabCase; lodash.last = last; lodash.lastIndexOf = array.lastIndexOf; +lodash.lt = lang.lt; +lodash.lte = lang.lte; lodash.max = math.max; lodash.min = math.min; lodash.noop = utility.noop; @@ -291,6 +295,7 @@ lodash.words = string.words; lodash.all = collection.every; lodash.any = collection.some; lodash.contains = collection.includes; +lodash.eq = lang.isEqual; lodash.detect = collection.find; lodash.foldl = collection.reduce; lodash.foldr = collection.reduceRight; diff --git a/math/max.js b/math/max.js index 50551746c..7187f0af9 100644 --- a/math/max.js +++ b/math/max.js @@ -1,5 +1,5 @@ -import arrayMax from '../internal/arrayMax'; import createExtremum from '../internal/createExtremum'; +import gt from '../lang/gt'; /** * Gets the maximum value of `collection`. If `collection` is empty or falsey @@ -48,6 +48,6 @@ import createExtremum from '../internal/createExtremum'; * _.max(users, 'age'); * // => { 'user': 'fred', 'age': 40 } */ -var max = createExtremum(arrayMax); +var max = createExtremum(gt, -Infinity); export default max; diff --git a/math/min.js b/math/min.js index f402c5c22..8971ec9c3 100644 --- a/math/min.js +++ b/math/min.js @@ -1,5 +1,5 @@ -import arrayMin from '../internal/arrayMin'; import createExtremum from '../internal/createExtremum'; +import lt from '../lang/lt'; /** * Gets the minimum value of `collection`. If `collection` is empty or falsey @@ -48,6 +48,6 @@ import createExtremum from '../internal/createExtremum'; * _.min(users, 'age'); * // => { 'user': 'barney', 'age': 36 } */ -var min = createExtremum(arrayMin, true); +var min = createExtremum(lt, Infinity); export default min; diff --git a/object/get.js b/object/get.js index 4fe6bcffa..01319ed4a 100644 --- a/object/get.js +++ b/object/get.js @@ -2,7 +2,7 @@ import baseGet from '../internal/baseGet'; import toPath from '../internal/toPath'; /** - * Gets the property value of `path` on `object`. If the resolved value is + * Gets the property value at `path` of `object`. If the resolved value is * `undefined` the `defaultValue` is used in its place. * * @static diff --git a/object/has.js b/object/has.js index 987e95322..a4f413c2a 100644 --- a/object/has.js +++ b/object/has.js @@ -1,6 +1,10 @@ import baseGet from '../internal/baseGet'; import baseSlice from '../internal/baseSlice'; +import isArguments from '../lang/isArguments'; +import isArray from '../lang/isArray'; +import isIndex from '../internal/isIndex'; import isKey from '../internal/isKey'; +import isLength from '../internal/isLength'; import last from '../array/last'; import toPath from '../internal/toPath'; @@ -40,10 +44,14 @@ function has(object, path) { if (!result && !isKey(path)) { path = toPath(path); object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } path = last(path); - result = object != null && hasOwnProperty.call(object, path); + result = hasOwnProperty.call(object, path); } - return result; + return result || (isLength(object.length) && isIndex(path, object.length) && + (isArray(object) || isArguments(object))); } export default has; diff --git a/object/keys.js b/object/keys.js index 7e3ccb969..f20a081ed 100644 --- a/object/keys.js +++ b/object/keys.js @@ -1,10 +1,10 @@ +import getNative from '../internal/getNative'; import isArrayLike from '../internal/isArrayLike'; -import isNative from '../lang/isNative'; import isObject from '../lang/isObject'; import shimKeys from '../internal/shimKeys'; /* Native method references for those with the same name as other `lodash` methods. */ -var nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys; +var nativeKeys = getNative(Object, 'keys'); /** * Creates an array of the own enumerable property names of `object`. @@ -34,7 +34,7 @@ var nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys; * // => ['0', '1'] */ var keys = !nativeKeys ? shimKeys : function(object) { - var Ctor = object != null && object.constructor; + var Ctor = object == null ? null : object.constructor; if ((typeof Ctor == 'function' && Ctor.prototype === object) || (typeof object != 'function' && isArrayLike(object))) { return shimKeys(object); diff --git a/object/keysIn.js b/object/keysIn.js index a1d763472..20b9dd281 100644 --- a/object/keysIn.js +++ b/object/keysIn.js @@ -3,7 +3,6 @@ import isArray from '../lang/isArray'; import isIndex from '../internal/isIndex'; import isLength from '../internal/isLength'; import isObject from '../lang/isObject'; -import support from '../support'; /** Used for native method references. */ var objectProto = Object.prototype; @@ -42,7 +41,7 @@ function keysIn(object) { } var length = object.length; length = (length && isLength(length) && - (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) || 0; + (isArray(object) || isArguments(object)) && length) || 0; var Ctor = object.constructor, index = -1, diff --git a/object/pairs.js b/object/pairs.js index 9f4b005d6..8a4caaf54 100644 --- a/object/pairs.js +++ b/object/pairs.js @@ -1,4 +1,5 @@ import keys from './keys'; +import toObject from '../internal/toObject'; /** * Creates a two dimensional array of the key-value pairs for `object`, @@ -15,6 +16,8 @@ import keys from './keys'; * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) */ function pairs(object) { + object = toObject(object); + var index = -1, props = keys(object), length = props.length, diff --git a/object/transform.js b/object/transform.js index b2fdf9fed..c350146d4 100644 --- a/object/transform.js +++ b/object/transform.js @@ -46,7 +46,7 @@ function transform(object, iteratee, accumulator, thisArg) { if (isArr) { accumulator = isArray(object) ? new Ctor : []; } else { - accumulator = baseCreate(isFunction(Ctor) && Ctor.prototype); + accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : null); } } else { accumulator = {}; diff --git a/package.json b/package.json index f2bccfcbd..87a1e5ba9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lodash-es", - "version": "3.8.0", + "version": "3.9.0", "description": "The modern build of lodash exported as ES modules.", "homepage": "https://lodash.com/custom-builds", "license": "MIT", diff --git a/string/escape.js b/string/escape.js index a373eaa9a..feaa8f7a7 100644 --- a/string/escape.js +++ b/string/escape.js @@ -13,7 +13,7 @@ var reUnescapedHtml = /[&<>"'`]/g, * use a third-party library like [_he_](https://mths.be/he). * * Though the ">" character is escaped for symmetry, characters like - * ">" and "/" don't require escaping in HTML and have no special meaning + * ">" and "/" don't need escaping in HTML and have no special meaning * unless they're part of a tag or unquoted attribute value. * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) * (under "semi-related fun fact") for more details. diff --git a/string/pad.js b/string/pad.js index c5a001a81..6e9f05315 100644 --- a/string/pad.js +++ b/string/pad.js @@ -10,7 +10,7 @@ var ceil = Math.ceil, var nativeIsFinite = root.isFinite; /** - * Pads `string` on the left and right sides if it is shorter than `length`. + * Pads `string` on the left and right sides if it's shorter than `length`. * Padding characters are truncated if they can't be evenly divided by `length`. * * @static diff --git a/string/padLeft.js b/string/padLeft.js index 1ee0355b7..a6c361317 100644 --- a/string/padLeft.js +++ b/string/padLeft.js @@ -1,7 +1,7 @@ import createPadDir from '../internal/createPadDir'; /** - * Pads `string` on the left side if it is shorter than `length`. Padding + * Pads `string` on the left side if it's shorter than `length`. Padding * characters are truncated if they exceed `length`. * * @static diff --git a/string/padRight.js b/string/padRight.js index 31103b69b..f4d8dfe97 100644 --- a/string/padRight.js +++ b/string/padRight.js @@ -1,7 +1,7 @@ import createPadDir from '../internal/createPadDir'; /** - * Pads `string` on the right side if it is shorter than `length`. Padding + * Pads `string` on the right side if it's shorter than `length`. Padding * characters are truncated if they exceed `length`. * * @static diff --git a/string/trunc.js b/string/trunc.js index 1b516c53b..c1dda1074 100644 --- a/string/trunc.js +++ b/string/trunc.js @@ -11,7 +11,7 @@ var DEFAULT_TRUNC_LENGTH = 30, var reFlags = /\w*$/; /** - * Truncates `string` if it is longer than the given maximum string length. + * Truncates `string` if it's longer than the given maximum string length. * The last characters of the truncated string are replaced with the omission * string which defaults to "...". * diff --git a/support.js b/support.js index 1657bfc65..181f6a1b9 100644 --- a/support.js +++ b/support.js @@ -1,13 +1,7 @@ import root from './internal/root'; -/** Used for native method references. */ -var objectProto = Object.prototype; - /** Used to detect DOM support. */ -var document = (document = root.window) && document.document; - -/** Native method references. */ -var propertyIsEnumerable = objectProto.propertyIsEnumerable; +var document = (document = root.window) ? document.document : null; /** * An object environment feature flags. @@ -20,31 +14,12 @@ var support = {}; (function(x) { var Ctor = function() { this.x = x; }, - args = arguments, object = { '0': x, 'length': x }, props = []; Ctor.prototype = { 'valueOf': x, 'y': x }; for (var key in new Ctor) { props.push(key); } - /** - * Detect if functions can be decompiled by `Function#toString` - * (all but Firefox OS certified apps, older Opera mobile browsers, and - * the PlayStation 3; forced `false` for Windows 8 apps). - * - * @memberOf _.support - * @type boolean - */ - support.funcDecomp = /\bthis\b/.test(function() { return this; }); - - /** - * Detect if `Function#name` is supported (all but IE). - * - * @memberOf _.support - * @type boolean - */ - support.funcNames = typeof Function.name == 'string'; - /** * Detect if the DOM is supported. * @@ -56,24 +31,6 @@ var support = {}; } catch(e) { support.dom = false; } - - /** - * Detect if `arguments` object indexes are non-enumerable. - * - * In Firefox < 4, IE < 9, PhantomJS, and Safari < 5.1 `arguments` object - * indexes are non-enumerable. Chrome < 25 and Node.js < 0.11.0 treat - * `arguments` object indexes as non-enumerable and fail `hasOwnProperty` - * checks for indexes that exceed the number of function parameters and - * whose associated argument values are `0`. - * - * @memberOf _.support - * @type boolean - */ - try { - support.nonEnumArgs = !propertyIsEnumerable.call(args, 1); - } catch(e) { - support.nonEnumArgs = true; - } }(1, 0)); export default support; diff --git a/utility/matchesProperty.js b/utility/matchesProperty.js index 4461dc4ab..1c4791cf1 100644 --- a/utility/matchesProperty.js +++ b/utility/matchesProperty.js @@ -13,7 +13,7 @@ import baseMatchesProperty from '../internal/baseMatchesProperty'; * @memberOf _ * @category Utility * @param {Array|string} path The path of the property to get. - * @param {*} value The value to compare. + * @param {*} srcValue The value to match. * @returns {Function} Returns the new function. * @example * @@ -25,8 +25,8 @@ import baseMatchesProperty from '../internal/baseMatchesProperty'; * _.find(users, _.matchesProperty('user', 'fred')); * // => { 'user': 'fred' } */ -function matchesProperty(path, value) { - return baseMatchesProperty(path, baseClone(value, true)); +function matchesProperty(path, srcValue) { + return baseMatchesProperty(path, baseClone(srcValue, true)); } export default matchesProperty; diff --git a/utility/mixin.js b/utility/mixin.js index c65c08e5f..a4231b497 100644 --- a/utility/mixin.js +++ b/utility/mixin.js @@ -35,9 +35,6 @@ var push = arrayProto.push; * }); * } * - * // use `_.runInContext` to avoid conflicts (esp. in Node.js) - * var _ = require('lodash').runInContext(); - * * _.mixin({ 'vowels': vowels }); * _.vowels('fred'); * // => ['e'] diff --git a/utility/times.js b/utility/times.js index efa4945b6..33de2e08e 100644 --- a/utility/times.js +++ b/utility/times.js @@ -9,7 +9,7 @@ var nativeIsFinite = root.isFinite, nativeMin = Math.min; /** Used as references for the maximum length and index of an array. */ -var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1; +var MAX_ARRAY_LENGTH = 4294967295; /** * Invokes the iteratee function `n` times, returning an array of the results