Change [[Class]] references to ES6 tag and add toString helper.

This commit is contained in:
John-David Dalton
2014-12-31 11:09:04 -06:00
parent b2e8359d31
commit d68321ac27
2 changed files with 188 additions and 175 deletions

359
lodash.js
View File

@@ -139,60 +139,60 @@
var templateCounter = -1; var templateCounter = -1;
/** `Object#toString` result references. */ /** `Object#toString` result references. */
var argsClass = '[object Arguments]', var argsTag = '[object Arguments]',
arrayClass = '[object Array]', arrayTag = '[object Array]',
boolClass = '[object Boolean]', boolTag = '[object Boolean]',
dateClass = '[object Date]', dateTag = '[object Date]',
errorClass = '[object Error]', errorTag = '[object Error]',
funcClass = '[object Function]', funcTag = '[object Function]',
mapClass = '[object Map]', mapTag = '[object Map]',
numberClass = '[object Number]', numberTag = '[object Number]',
objectClass = '[object Object]', objectTag = '[object Object]',
regexpClass = '[object RegExp]', regexpTag = '[object RegExp]',
setClass = '[object Set]', setTag = '[object Set]',
stringClass = '[object String]', stringTag = '[object String]',
weakMapClass = '[object WeakMap]'; weakMapTag = '[object WeakMap]';
var arrayBufferClass = '[object ArrayBuffer]', var arrayBufferTag = '[object ArrayBuffer]',
float32Class = '[object Float32Array]', float32Tag = '[object Float32Array]',
float64Class = '[object Float64Array]', float64Tag = '[object Float64Array]',
int8Class = '[object Int8Array]', int8Tag = '[object Int8Array]',
int16Class = '[object Int16Array]', int16Tag = '[object Int16Array]',
int32Class = '[object Int32Array]', int32Tag = '[object Int32Array]',
uint8Class = '[object Uint8Array]', uint8Tag = '[object Uint8Array]',
uint8ClampedClass = '[object Uint8ClampedArray]', uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Class = '[object Uint16Array]', uint16Tag = '[object Uint16Array]',
uint32Class = '[object Uint32Array]'; uint32Tag = '[object Uint32Array]';
/** Used to identify object classifications that are treated like arrays. */ /** Used to identify object classifications that are treated like arrays. */
var arrayLikeClasses = {}; var arrayLikeTags = {};
arrayLikeClasses[argsClass] = arrayLikeTags[argsTag] =
arrayLikeClasses[arrayClass] = arrayLikeClasses[float32Class] = arrayLikeTags[arrayTag] = arrayLikeTags[float32Tag] =
arrayLikeClasses[float64Class] = arrayLikeClasses[int8Class] = arrayLikeTags[float64Tag] = arrayLikeTags[int8Tag] =
arrayLikeClasses[int16Class] = arrayLikeClasses[int32Class] = arrayLikeTags[int16Tag] = arrayLikeTags[int32Tag] =
arrayLikeClasses[uint8Class] = arrayLikeClasses[uint8ClampedClass] = arrayLikeTags[uint8Tag] = arrayLikeTags[uint8ClampedTag] =
arrayLikeClasses[uint16Class] = arrayLikeClasses[uint32Class] = true; arrayLikeTags[uint16Tag] = arrayLikeTags[uint32Tag] = true;
arrayLikeClasses[arrayBufferClass] = arrayLikeClasses[boolClass] = arrayLikeTags[arrayBufferTag] = arrayLikeTags[boolTag] =
arrayLikeClasses[dateClass] = arrayLikeClasses[errorClass] = arrayLikeTags[dateTag] = arrayLikeTags[errorTag] =
arrayLikeClasses[funcClass] = arrayLikeClasses[mapClass] = arrayLikeTags[funcTag] = arrayLikeTags[mapTag] =
arrayLikeClasses[numberClass] = arrayLikeClasses[objectClass] = arrayLikeTags[numberTag] = arrayLikeTags[objectTag] =
arrayLikeClasses[regexpClass] = arrayLikeClasses[setClass] = arrayLikeTags[regexpTag] = arrayLikeTags[setTag] =
arrayLikeClasses[stringClass] = arrayLikeClasses[weakMapClass] = false; arrayLikeTags[stringTag] = arrayLikeTags[weakMapTag] = false;
/** Used to identify object classifications that `_.clone` supports. */ /** Used to identify object classifications that `_.clone` supports. */
var cloneableClasses = {}; var cloneableTags = {};
cloneableClasses[argsClass] = cloneableClasses[arrayClass] = cloneableTags[argsTag] = cloneableTags[arrayTag] =
cloneableClasses[arrayBufferClass] = cloneableClasses[boolClass] = cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
cloneableClasses[dateClass] = cloneableClasses[float32Class] = cloneableTags[dateTag] = cloneableTags[float32Tag] =
cloneableClasses[float64Class] = cloneableClasses[int8Class] = cloneableTags[float64Tag] = cloneableTags[int8Tag] =
cloneableClasses[int16Class] = cloneableClasses[int32Class] = cloneableTags[int16Tag] = cloneableTags[int32Tag] =
cloneableClasses[numberClass] = cloneableClasses[objectClass] = cloneableTags[numberTag] = cloneableTags[objectTag] =
cloneableClasses[regexpClass] = cloneableClasses[stringClass] = cloneableTags[regexpTag] = cloneableTags[stringTag] =
cloneableClasses[uint8Class] = cloneableClasses[uint8ClampedClass] = cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
cloneableClasses[uint16Class] = cloneableClasses[uint32Class] = true; cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
cloneableClasses[errorClass] = cloneableTags[errorTag] =
cloneableClasses[funcClass] = cloneableClasses[mapClass] = cloneableTags[funcTag] = cloneableTags[mapTag] =
cloneableClasses[setClass] = cloneableClasses[weakMapClass] = false; cloneableTags[setTag] = cloneableTags[weakMapTag] = false;
/** Used as an internal `_.debounce` options object by `_.throttle`. */ /** Used as an internal `_.debounce` options object by `_.throttle`. */
var debounceOptions = { var debounceOptions = {
@@ -700,7 +700,7 @@
*/ */
var isHostObject = (function() { var isHostObject = (function() {
try { try {
String({ 'toString': 0 } + ''); Object({ 'toString': 0 } + '');
} catch(e) { } catch(e) {
return function() { return false; }; return function() { return false; };
} }
@@ -911,15 +911,15 @@
/** Used to generate unique IDs. */ /** Used to generate unique IDs. */
var idCounter = 0; var idCounter = 0;
/** Used to resolve the internal tag of values. */
var objToString = objectProto.toString;
/** Used to restore the original `_` reference in `_.noConflict`. */ /** Used to restore the original `_` reference in `_.noConflict`. */
var oldDash = context._; var oldDash = context._;
/** Used to resolve the internal `[[Class]]` of values. */
var toString = objectProto.toString;
/** Used to detect if a method is native. */ /** Used to detect if a method is native. */
var reNative = RegExp('^' + var reNative = RegExp('^' +
escapeRegExp(toString) escapeRegExp(objToString)
.replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
); );
@@ -984,29 +984,29 @@
/** Used to store function metadata. */ /** Used to store function metadata. */
var metaMap = WeakMap && new WeakMap; var metaMap = WeakMap && new WeakMap;
/** Used to lookup a built-in constructor by `[[Class]]`. */ /** Used to lookup a built-in constructor by internal tag. */
var ctorByClass = {}; var ctorByTag = {};
ctorByClass[float32Class] = context.Float32Array; ctorByTag[float32Tag] = context.Float32Array;
ctorByClass[float64Class] = context.Float64Array; ctorByTag[float64Tag] = context.Float64Array;
ctorByClass[int8Class] = context.Int8Array; ctorByTag[int8Tag] = context.Int8Array;
ctorByClass[int16Class] = context.Int16Array; ctorByTag[int16Tag] = context.Int16Array;
ctorByClass[int32Class] = context.Int32Array; ctorByTag[int32Tag] = context.Int32Array;
ctorByClass[uint8Class] = context.Uint8Array; ctorByTag[uint8Tag] = context.Uint8Array;
ctorByClass[uint8ClampedClass] = context.Uint8ClampedArray; ctorByTag[uint8ClampedTag] = context.Uint8ClampedArray;
ctorByClass[uint16Class] = context.Uint16Array; ctorByTag[uint16Tag] = context.Uint16Array;
ctorByClass[uint32Class] = context.Uint32Array; ctorByTag[uint32Tag] = context.Uint32Array;
/** Used to avoid iterating over non-enumerable properties in IE < 9. */ /** Used to avoid iterating over non-enumerable properties in IE < 9. */
var nonEnumProps = {}; var nonEnumProps = {};
nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true };
nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true };
nonEnumProps[objectClass] = { 'constructor': true }; nonEnumProps[objectTag] = { 'constructor': true };
arrayEach(shadowProps, function(key) { arrayEach(shadowProps, function(key) {
for (var className in nonEnumProps) { for (var tag in nonEnumProps) {
if (hasOwnProperty.call(nonEnumProps, className)) { if (hasOwnProperty.call(nonEnumProps, tag)) {
var props = nonEnumProps[className]; var props = nonEnumProps[tag];
props[key] = hasOwnProperty.call(props, key); props[key] = hasOwnProperty.call(props, key);
} }
} }
@@ -1139,13 +1139,13 @@
for (var key in new Ctor) { props.push(key); } for (var key in new Ctor) { props.push(key); }
/** /**
* Detect if the `[[Class]]` of `arguments` objects is resolvable * Detect if the internal tag of `arguments` objects is resolvable
* (all but Firefox < 4, IE < 9). * (all but Firefox < 4, IE < 9).
* *
* @memberOf _.support * @memberOf _.support
* @type boolean * @type boolean
*/ */
support.argsClass = toString.call(arguments) == argsClass; support.argsTag = objToString.call(arguments) == argsTag;
/** /**
* Detect if `name` or `message` properties of `Error.prototype` are * Detect if `name` or `message` properties of `Error.prototype` are
@@ -1189,12 +1189,12 @@
support.funcNames = typeof Function.name == 'string'; support.funcNames = typeof Function.name == 'string';
/** /**
* Detect if the `[[Class]]` of DOM nodes is resolvable (all but IE < 9). * Detect if the internal tag of DOM nodes is resolvable (all but IE < 9).
* *
* @memberOf _.support * @memberOf _.support
* @type boolean * @type boolean
*/ */
support.nodeClass = toString.call(document) != objectClass; support.nodeTag = objToString.call(document) != objectTag;
/** /**
* Detect if string indexes are non-enumerable * Detect if string indexes are non-enumerable
@@ -1778,7 +1778,7 @@
// Handle "_.pluck" and "_.where" style callback shorthands. // Handle "_.pluck" and "_.where" style callback shorthands.
return type == 'object' return type == 'object'
? baseMatches(func, argCount) ? baseMatches(func, argCount)
: baseProperty(argCount ? String(func) : func); : baseProperty(argCount ? (func + '') : func);
} }
/** /**
@@ -1813,7 +1813,7 @@
isDeep = false; isDeep = false;
result = {}; result = {};
} else if (isDeep) { } else if (isDeep) {
isDeep = toString.call(result) == objectClass; isDeep = objToString.call(result) == objectTag;
} }
} }
if (!isDeep || result === value) { if (!isDeep || result === value) {
@@ -2261,31 +2261,31 @@
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/ */
function baseIsEqualDeep(object, other, equalFunc, customizer, isWhere, stackA, stackB) { function baseIsEqualDeep(object, other, equalFunc, customizer, isWhere, stackA, stackB) {
var objClass = isArray(object) ? arrayClass : toString.call(object), var objTag = isArray(object) ? arrayTag : objToString.call(object),
objIsArg = objClass == argsClass, objIsArg = objTag == argsTag,
objIsArr = !objIsArg && arrayLikeClasses[objClass], objIsArr = !objIsArg && arrayLikeTags[objTag],
othClass = isArray(other) ? arrayClass : toString.call(other), othTag = isArray(other) ? arrayTag : objToString.call(other),
othIsArg = othClass == argsClass, othIsArg = othTag == argsTag,
othIsArr = !othIsArg && arrayLikeClasses[othClass]; othIsArr = !othIsArg && arrayLikeTags[othTag];
if (!lodash.support.argsClass) { if (!lodash.support.argsTag) {
objIsArg = !objIsArr && typeof object.length == 'number' && isArguments(object); objIsArg = !objIsArr && typeof object.length == 'number' && isArguments(object);
othIsArg = !othIsArr && typeof other.length == 'number' && isArguments(other); othIsArg = !othIsArr && typeof other.length == 'number' && isArguments(other);
} }
if (objIsArg) { if (objIsArg) {
object = argsToObject(object); object = argsToObject(object);
objClass = objectClass; objTag = objectTag;
} }
if (othIsArg) { if (othIsArg) {
other = argsToObject(other); other = argsToObject(other);
othClass = objectClass; othTag = objectTag;
} }
var objIsObj = objClass == objectClass && !isHostObject(object), var objIsObj = objTag == objectTag && !isHostObject(object),
othIsObj = othClass == objectClass && !isHostObject(other), othIsObj = othTag == objectTag && !isHostObject(other),
isSameClass = objClass == othClass; isSameTag = objTag == othTag;
if (isSameClass && !(objIsArr || objIsObj)) { if (isSameTag && !(objIsArr || objIsObj)) {
return equalByClass(object, other, objClass); return equalByTag(object, other, objTag);
} }
var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
@@ -2293,7 +2293,7 @@
if (valWrapped || othWrapped) { if (valWrapped || othWrapped) {
return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isWhere, stackA, stackB); return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isWhere, stackA, stackB);
} }
if (!isSameClass) { if (!isSameTag) {
return false; return false;
} }
// Assume cyclic structures are equal. // Assume cyclic structures are equal.
@@ -3188,7 +3188,7 @@
return ''; return '';
} }
var padLength = length - strLength; var padLength = length - strLength;
chars = chars == null ? ' ' : String(chars); chars = chars == null ? ' ' : (chars + '');
return repeat(chars, ceil(padLength / chars.length)).slice(0, padLength); return repeat(chars, ceil(padLength / chars.length)).slice(0, padLength);
} }
@@ -3348,40 +3348,40 @@
/** /**
* A specialized version of `baseIsEqualDeep` for comparing objects of * A specialized version of `baseIsEqualDeep` for comparing objects of
* the same `[[Class]]`. * the same internal tag.
* *
* **Note:** This function only supports comparing values with `[[Class]]` * **Note:** This function only supports comparing values with internal tag
* values of `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. * values of `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
* *
* @private * @private
* @param {Object} value The object to compare to `other`. * @param {Object} value The object to compare to `other`.
* @param {Object} other The object to compare to `object`. * @param {Object} other The object to compare to `object`.
* @param {string} className The `[[Class]]` of the objects to compare. * @param {string} tag The tag of the objects to compare.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/ */
function equalByClass(object, other, className) { function equalByTag(object, other, tag) {
switch (className) { switch (tag) {
case boolClass: case boolTag:
case dateClass: case dateTag:
// Coerce dates and booleans to numbers, dates to milliseconds and booleans // Coerce dates and booleans to numbers, dates to milliseconds and booleans
// to `1` or `0` treating invalid dates coerced to `NaN` as not equal. // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
return +object == +other; return +object == +other;
case errorClass: case errorTag:
return object.name == other.name && object.message == other.message; return object.name == other.name && object.message == other.message;
case numberClass: case numberTag:
// Treat `NaN` vs. `NaN` as equal. // Treat `NaN` vs. `NaN` as equal.
return (object != +object) return (object != +object)
? other != +other ? other != +other
// But, treat `-0` vs. `+0` as not equal. // But, treat `-0` vs. `+0` as not equal.
: (object == 0 ? ((1 / object) == (1 / other)) : object == +other); : (object == 0 ? ((1 / object) == (1 / other)) : object == +other);
case regexpClass: case regexpTag:
case stringClass: case stringTag:
// Coerce regexes to strings (http://es5.github.io/#x15.10.6.4) and // Coerce regexes to strings (http://es5.github.io/#x15.10.6.4) and
// treat strings primitives and string objects as equal. // treat strings primitives and string objects as equal.
return object == String(other); return object == (other + '');
} }
return false; return false;
} }
@@ -3584,9 +3584,9 @@
return null; return null;
} }
var Ctor = object.constructor, var Ctor = object.constructor,
className = toString.call(object), tag = objToString.call(object),
isArgs = className == argsClass || (!lodash.support.argsClass && isArguments(object)), isArgs = tag == argsTag || (!lodash.support.argsTag && isArguments(object)),
isObj = className == objectClass; isObj = tag == objectTag;
if (isObj && !(typeof Ctor == 'function' && Ctor instanceof Ctor)) { if (isObj && !(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
Ctor = Object; Ctor = Object;
@@ -3598,29 +3598,29 @@
} }
return result; return result;
} }
switch (className) { switch (tag) {
case arrayBufferClass: case arrayBufferTag:
return bufferClone(object); return bufferClone(object);
case boolClass: case boolTag:
case dateClass: case dateTag:
return new Ctor(+object); return new Ctor(+object);
case float32Class: case float64Class: case float32Tag: case float64Tag:
case int8Class: case int16Class: case int32Class: case int8Tag: case int16Tag: case int32Tag:
case uint8Class: case uint8ClampedClass: case uint16Class: case uint32Class: case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
// Safari 5 mobile incorrectly has `Object` as the constructor of typed arrays. // Safari 5 mobile incorrectly has `Object` as the constructor of typed arrays.
if (Ctor instanceof Ctor) { if (Ctor instanceof Ctor) {
Ctor = ctorByClass[className]; Ctor = ctorByTag[tag];
} }
var buffer = object.buffer; var buffer = object.buffer;
return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);
case numberClass: case numberTag:
case stringClass: case stringTag:
return new Ctor(object); return new Ctor(object);
case regexpClass: case regexpTag:
result = new Ctor(object.source, reFlags.exec(object)); result = new Ctor(object.source, reFlags.exec(object));
result.lastIndex = object.lastIndex; result.lastIndex = object.lastIndex;
} }
@@ -3636,7 +3636,7 @@
*/ */
function isArrayLike(value) { function isArrayLike(value) {
return (isObjectLike(value) && isLength(value.length) && return (isObjectLike(value) && isLength(value.length) &&
(arrayLikeClasses[toString.call(value)] || (!lodash.support.argsClass && isArguments(value)))) || false; (arrayLikeTags[objToString.call(value)] || (!lodash.support.argsTag && isArguments(value)))) || false;
} }
/** /**
@@ -3672,7 +3672,7 @@
* @returns {boolean} Returns `true` if `value` is cloneable, else `false`. * @returns {boolean} Returns `true` if `value` is cloneable, else `false`.
*/ */
function isCloneable(value) { function isCloneable(value) {
return (value && cloneableClasses[toString.call(value)] && !isHostObject(value)) || false; return (value && cloneableTags[objToString.call(value)] && !isHostObject(value)) || false;
} }
/** /**
@@ -3913,10 +3913,10 @@
support = lodash.support; support = lodash.support;
// Exit early for non `Object` objects. // Exit early for non `Object` objects.
if (!(isObjectLike(value) && toString.call(value) == objectClass && !isHostObject(value)) || if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value)) ||
(!hasOwnProperty.call(value, 'constructor') && (!hasOwnProperty.call(value, 'constructor') &&
(Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor))) || (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor))) ||
(!support.argsClass && isArguments(value))) { (!support.argsTag && isArguments(value))) {
return false; return false;
} }
// IE < 9 iterates inherited properties before own properties. If the first // IE < 9 iterates inherited properties before own properties. If the first
@@ -4010,6 +4010,21 @@
return isObject(value) ? value : Object(value); return isObject(value) ? value : Object(value);
} }
/**
* Converts `value` to a string if it not one. An empty string is returned
* for `null` or `undefined` values.
*
* @private
* @param {*} value The value to process.
* @returns {string} Returns the string.
*/
function toString(value) {
if (typeof value == 'string') {
return value;
}
return value == null ? '' : (value + '');
}
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/** /**
@@ -4051,7 +4066,7 @@
/** /**
* Creates an array with all falsey values removed. The values `false`, `null`, * Creates an array with all falsey values removed. The values `false`, `null`,
* `0`, `""`, `undefined`, and `NaN` are all falsey. * `0`, `""`, `undefined`, and `NaN` are falsey.
* *
* @static * @static
* @memberOf _ * @memberOf _
@@ -5452,7 +5467,7 @@
* // => '1,2,3' * // => '1,2,3'
*/ */
function wrapperToString() { function wrapperToString() {
return String(this.value()); return (this.value() + '');
} }
/** /**
@@ -7650,10 +7665,10 @@
*/ */
function isArguments(value) { function isArguments(value) {
var length = isObjectLike(value) ? value.length : undefined; var length = isObjectLike(value) ? value.length : undefined;
return (isLength(length) && toString.call(value) == argsClass) || false; return (isLength(length) && objToString.call(value) == argsTag) || false;
} }
// Fallback for environments without a `[[Class]]` for `arguments` objects. // Fallback for environments without an internal tag for `arguments` objects.
if (!support.argsClass) { if (!support.argsTag) {
isArguments = function(value) { isArguments = function(value) {
var length = isObjectLike(value) ? value.length : undefined; var length = isObjectLike(value) ? value.length : undefined;
return (isLength(length) && hasOwnProperty.call(value, 'callee') && return (isLength(length) && hasOwnProperty.call(value, 'callee') &&
@@ -7678,7 +7693,7 @@
* // => false * // => false
*/ */
var isArray = nativeIsArray || function(value) { var isArray = nativeIsArray || function(value) {
return (isObjectLike(value) && isLength(value.length) && toString.call(value) == arrayClass) || false; return (isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag) || false;
}; };
/** /**
@@ -7698,7 +7713,7 @@
* // => false * // => false
*/ */
function isBoolean(value) { function isBoolean(value) {
return (value === true || value === false || isObjectLike(value) && toString.call(value) == boolClass) || false; return (value === true || value === false || isObjectLike(value) && objToString.call(value) == boolTag) || false;
} }
/** /**
@@ -7718,7 +7733,7 @@
* // => false * // => false
*/ */
function isDate(value) { function isDate(value) {
return (isObjectLike(value) && toString.call(value) == dateClass) || false; return (isObjectLike(value) && objToString.call(value) == dateTag) || false;
} }
/** /**
@@ -7739,7 +7754,7 @@
*/ */
function isElement(value) { function isElement(value) {
return (value && value.nodeType === 1 && isObjectLike(value) && return (value && value.nodeType === 1 && isObjectLike(value) &&
(lodash.support.nodeClass ? toString.call(value).indexOf('Element') > -1 : isHostObject(value))) || false; (lodash.support.nodeTag ? objToString.call(value).indexOf('Element') > -1 : isHostObject(value))) || false;
} }
// Fallback for environments without DOM support. // Fallback for environments without DOM support.
if (!support.dom) { if (!support.dom) {
@@ -7853,7 +7868,7 @@
* // => false * // => false
*/ */
function isError(value) { function isError(value) {
return (isObjectLike(value) && typeof value.message == 'string' && toString.call(value) == errorClass) || false; return (isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag) || false;
} }
/** /**
@@ -7916,7 +7931,7 @@
// The use of `Object#toString` avoids issues with the `typeof` operator // The use of `Object#toString` avoids issues with the `typeof` operator
// in older versions of Chrome and Safari which return 'function' for regexes // in older versions of Chrome and Safari which return 'function' for regexes
// and Safari 8 equivalents which return 'object' for typed array constructors. // and Safari 8 equivalents which return 'object' for typed array constructors.
return toString.call(value) == funcClass; return objToString.call(value) == funcTag;
}; };
} }
@@ -8038,7 +8053,7 @@
*/ */
function isNaN(value) { function isNaN(value) {
// `NaN` as a primitive is the only value that is not equal to itself // `NaN` as a primitive is the only value that is not equal to itself
// (perform the `[[Class]]` check first to avoid errors with some host objects in IE). // (perform the tag check first to avoid errors with some host objects in IE).
return isNumber(value) && value != +value; return isNumber(value) && value != +value;
} }
@@ -8062,7 +8077,7 @@
if (value == null) { if (value == null) {
return false; return false;
} }
if (toString.call(value) == funcClass) { if (objToString.call(value) == funcTag) {
return reNative.test(fnToString.call(value)); return reNative.test(fnToString.call(value));
} }
return (isObjectLike(value) && return (isObjectLike(value) &&
@@ -8112,7 +8127,7 @@
* // => false * // => false
*/ */
function isNumber(value) { function isNumber(value) {
return typeof value == 'number' || (isObjectLike(value) && toString.call(value) == numberClass) || false; return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag) || false;
} }
/** /**
@@ -8147,7 +8162,7 @@
* // => true * // => true
*/ */
var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
if (!(value && toString.call(value) == objectClass) || (!lodash.support.argsClass && isArguments(value))) { if (!(value && objToString.call(value) == objectTag) || (!lodash.support.argsTag && isArguments(value))) {
return false; return false;
} }
var valueOf = value.valueOf, var valueOf = value.valueOf,
@@ -8175,7 +8190,7 @@
* // => false * // => false
*/ */
function isRegExp(value) { function isRegExp(value) {
return (isObject(value) && toString.call(value) == regexpClass) || false; return (isObject(value) && objToString.call(value) == regexpTag) || false;
} }
/** /**
@@ -8195,7 +8210,7 @@
* // => false * // => false
*/ */
function isString(value) { function isString(value) {
return typeof value == 'string' || (isObjectLike(value) && toString.call(value) == stringClass) || false; return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag) || false;
} }
/** /**
@@ -8683,7 +8698,7 @@
skipProto = support.enumPrototypes && typeof object == 'function'; skipProto = support.enumPrototypes && typeof object == 'function';
while (++index < length) { while (++index < length) {
result[index] = String(index); result[index] = (index + '');
} }
// Lo-Dash skips the `constructor` property when it infers it is iterating // Lo-Dash skips the `constructor` property when it infers it is iterating
// over a `prototype` object because IE < 9 can't set the `[[Enumerable]]` // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`
@@ -8698,10 +8713,10 @@
} }
} }
if (support.nonEnumShadows && object !== objectProto) { if (support.nonEnumShadows && object !== objectProto) {
var className = object === stringProto ? stringClass : object === errorProto ? errorClass : toString.call(object), var tag = object === stringProto ? stringTag : object === errorProto ? errorTag : objToString.call(object),
nonEnums = nonEnumProps[className] || nonEnumProps[objectClass]; nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag];
if (className == objectClass) { if (tag == objectTag) {
proto = objectProto; proto = objectProto;
} }
length = shadowProps.length; length = shadowProps.length;
@@ -9113,7 +9128,7 @@
} }
if (floating || min % 1 || max % 1) { if (floating || min % 1 || max % 1) {
var rand = nativeRandom(); var rand = nativeRandom();
return nativeMin(min + (rand * (max - min + parseFloat('1e-' + (String(rand).length - 1)))), max); return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max);
} }
return baseRandom(min, max); return baseRandom(min, max);
} }
@@ -9159,7 +9174,7 @@
* // => 'Fred' * // => 'Fred'
*/ */
function capitalize(string) { function capitalize(string) {
string = string == null ? '' : String(string); string = toString(string);
return string ? (string.charAt(0).toUpperCase() + string.slice(1)) : string; return string ? (string.charAt(0).toUpperCase() + string.slice(1)) : string;
} }
@@ -9179,7 +9194,7 @@
* // => 'deja vu' * // => 'deja vu'
*/ */
function deburr(string) { function deburr(string) {
string = string == null ? '' : String(string); string = toString(string);
return string ? string.replace(reLatin1, deburrLetter) : string; return string ? string.replace(reLatin1, deburrLetter) : string;
} }
@@ -9205,8 +9220,8 @@
* // => true * // => true
*/ */
function endsWith(string, target, position) { function endsWith(string, target, position) {
string = string == null ? '' : String(string); string = toString(string);
target = String(target); target = (target + '');
var length = string.length; var length = string.length;
position = (typeof position == 'undefined' ? length : nativeMin(position < 0 ? 0 : (+position || 0), length)) - target.length; position = (typeof position == 'undefined' ? length : nativeMin(position < 0 ? 0 : (+position || 0), length)) - target.length;
@@ -9247,7 +9262,7 @@
*/ */
function escape(string) { function escape(string) {
// Reset `lastIndex` because in IE < 9 `String#replace` does not. // Reset `lastIndex` because in IE < 9 `String#replace` does not.
string = string == null ? '' : String(string); string = toString(string);
return (string && reHasUnescapedHtml.test(string)) return (string && reHasUnescapedHtml.test(string))
? string.replace(reUnescapedHtml, escapeHtmlChar) ? string.replace(reUnescapedHtml, escapeHtmlChar)
: string; : string;
@@ -9268,7 +9283,7 @@
* // => '\[lodash\]\(https://lodash\.com/\)' * // => '\[lodash\]\(https://lodash\.com/\)'
*/ */
function escapeRegExp(string) { function escapeRegExp(string) {
string = string == null ? '' : String(string); string = toString(string);
return (string && reHasRegExpChars.test(string)) return (string && reHasRegExpChars.test(string))
? string.replace(reRegExpChars, '\\$&') ? string.replace(reRegExpChars, '\\$&')
: string; : string;
@@ -9323,7 +9338,7 @@
* // => 'abc' * // => 'abc'
*/ */
function pad(string, length, chars) { function pad(string, length, chars) {
string = string == null ? '' : String(string); string = toString(string);
length = +length; length = +length;
var strLength = string.length; var strLength = string.length;
@@ -9362,7 +9377,7 @@
* // => 'abc' * // => 'abc'
*/ */
function padLeft(string, length, chars) { function padLeft(string, length, chars) {
string = string == null ? '' : String(string); string = toString(string);
return string ? (createPad(string, length, chars) + string) : string; return string ? (createPad(string, length, chars) + string) : string;
} }
@@ -9390,7 +9405,7 @@
* // => 'abc' * // => 'abc'
*/ */
function padRight(string, length, chars) { function padRight(string, length, chars) {
string = string == null ? '' : String(string); string = toString(string);
return string ? (string + createPad(string, length, chars)) : string; return string ? (string + createPad(string, length, chars)) : string;
} }
@@ -9459,7 +9474,7 @@
if (n < 1 || string == null || !nativeIsFinite(n)) { if (n < 1 || string == null || !nativeIsFinite(n)) {
return result; return result;
} }
string = String(string); string = (string + '');
// Leverage the exponentiation by squaring algorithm for a faster repeat. // Leverage the exponentiation by squaring algorithm for a faster repeat.
// See http://en.wikipedia.org/wiki/Exponentiation_by_squaring. // See http://en.wikipedia.org/wiki/Exponentiation_by_squaring.
@@ -9520,7 +9535,7 @@
* // => true * // => true
*/ */
function startsWith(string, target, position) { function startsWith(string, target, position) {
string = string == null ? '' : String(string); string = toString(string);
position = position == null ? 0 : nativeMin(position < 0 ? 0 : (+position || 0), string.length); position = position == null ? 0 : nativeMin(position < 0 ? 0 : (+position || 0), string.length);
return string.lastIndexOf(target, position) == position; return string.lastIndexOf(target, position) == position;
} }
@@ -9629,7 +9644,7 @@
if (otherOptions && isIterateeCall(string, options, otherOptions)) { if (otherOptions && isIterateeCall(string, options, otherOptions)) {
options = otherOptions = null; options = otherOptions = null;
} }
string = String(string == null ? '' : string); string = toString(string);
options = baseAssign(baseAssign({}, otherOptions || options), settings, assignOwnDefaults); options = baseAssign(baseAssign({}, otherOptions || options), settings, assignOwnDefaults);
var imports = baseAssign(baseAssign({}, options.imports), settings.imports, assignOwnDefaults), var imports = baseAssign(baseAssign({}, options.imports), settings.imports, assignOwnDefaults),
@@ -9748,14 +9763,14 @@
*/ */
function trim(string, chars, guard) { function trim(string, chars, guard) {
var value = string; var value = string;
string = string == null ? '' : String(string); string = toString(string);
if (!string) { if (!string) {
return string; return string;
} }
if (guard ? isIterateeCall(value, chars, guard) : chars == null) { if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1); return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1);
} }
chars = String(chars); chars = (chars + '');
return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1); return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1);
} }
@@ -9779,15 +9794,14 @@
*/ */
function trimLeft(string, chars, guard) { function trimLeft(string, chars, guard) {
var value = string; var value = string;
string = string == null ? '' : String(string); string = toString(string);
if (!string) { if (!string) {
return string; return string;
} }
if (guard ? isIterateeCall(value, chars, guard) : chars == null) { if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
return string.slice(trimmedLeftIndex(string)) return string.slice(trimmedLeftIndex(string))
} }
chars = String(chars); return string.slice(charsLeftIndex(string, (chars + '')));
return string.slice(charsLeftIndex(string, chars));
} }
/** /**
@@ -9810,15 +9824,14 @@
*/ */
function trimRight(string, chars, guard) { function trimRight(string, chars, guard) {
var value = string; var value = string;
string = string == null ? '' : String(string); string = toString(string);
if (!string) { if (!string) {
return string; return string;
} }
if (guard ? isIterateeCall(value, chars, guard) : chars == null) { if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
return string.slice(0, trimmedRightIndex(string) + 1) return string.slice(0, trimmedRightIndex(string) + 1)
} }
chars = String(chars); return string.slice(0, charsRightIndex(string, (chars + '')) + 1);
return string.slice(0, charsRightIndex(string, chars) + 1);
} }
/** /**
@@ -9863,12 +9876,12 @@
if (isObject(options)) { if (isObject(options)) {
var separator = 'separator' in options ? options.separator : separator; var separator = 'separator' in options ? options.separator : separator;
length = 'length' in options ? +options.length || 0 : length; length = 'length' in options ? +options.length || 0 : length;
omission = 'omission' in options ? String(options.omission) : omission; omission = 'omission' in options ? (options.omission + '') : omission;
} }
else if (options != null) { else if (options != null) {
length = +options || 0; length = +options || 0;
} }
string = string == null ? '' : String(string); string = toString(string);
if (length >= string.length) { if (length >= string.length) {
return string; return string;
} }
@@ -9923,7 +9936,7 @@
* // => 'fred, barney, & pebbles' * // => 'fred, barney, & pebbles'
*/ */
function unescape(string) { function unescape(string) {
string = string == null ? '' : String(string); string = toString(string);
return (string && reHasEscapedHtml.test(string)) return (string && reHasEscapedHtml.test(string))
? string.replace(reEscapedHtml, unescapeHtmlChar) ? string.replace(reEscapedHtml, unescapeHtmlChar)
: string; : string;
@@ -9951,8 +9964,8 @@
if (guard && isIterateeCall(string, pattern, guard)) { if (guard && isIterateeCall(string, pattern, guard)) {
pattern = null; pattern = null;
} }
string = string != null && String(string); string = toString(string);
return (string && string.match(pattern || reWords)) || []; return string.match(pattern || reWords) || [];
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
@@ -10234,7 +10247,7 @@
* // => ['barney', 'fred'] * // => ['barney', 'fred']
*/ */
function property(key) { function property(key) {
return baseProperty(String(key)); return baseProperty(key + '');
} }
/** /**
@@ -10383,7 +10396,7 @@
*/ */
function uniqueId(prefix) { function uniqueId(prefix) {
var id = ++idCounter; var id = ++idCounter;
return String(prefix == null ? '' : prefix) + id; return toString(prefix) + id;
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/

View File

@@ -11884,7 +11884,7 @@
test('should not contain minified properties (test production builds)', 1, function() { test('should not contain minified properties (test production builds)', 1, function() {
var props = [ var props = [
'argsClass', 'argsTag',
'argsObject', 'argsObject',
'dom', 'dom',
'enumErrorProps', 'enumErrorProps',
@@ -11893,7 +11893,7 @@
'funcDecomp', 'funcDecomp',
'funcNames', 'funcNames',
'hostObject', 'hostObject',
'nodeClass', 'nodeTag',
'nonEnumArgs', 'nonEnumArgs',
'nonEnumShadows', 'nonEnumShadows',
'nonEnumStrings', 'nonEnumStrings',