From de70ef1ef6b1eb2daa4785ea5daa946288eac285 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 23 Mar 2014 14:11:54 -0700 Subject: [PATCH] Remove `a` and `b` use from `baseIsEqual`. --- dist/lodash.underscore.js | 86 +++++++++++++-------------- lodash.js | 121 ++++++++++++++++++++------------------ 2 files changed, 107 insertions(+), 100 deletions(-) diff --git a/dist/lodash.underscore.js b/dist/lodash.underscore.js index 2fbe76694..7e1a01b8b 100644 --- a/dist/lodash.underscore.js +++ b/dist/lodash.underscore.js @@ -777,61 +777,61 @@ * @param {Array} [stackB=[]] Tracks traversed `other` objects. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. */ - function baseIsEqual(a, b, stackA, stackB) { - if (a === b) { - return a !== 0 || (1 / a == 1 / b); + function baseIsEqual(value, other, stackA, stackB) { + if (value === other) { + return value !== 0 || (1 / value == 1 / other); } - var type = typeof a, - otherType = typeof b; + var valType = typeof value, + othType = typeof other; - if (a === a && (a == null || b == null || - (type != 'function' && type != 'object' && otherType != 'function' && otherType != 'object'))) { + if (value === value && (value == null || other == null || + (valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object'))) { return false; } - var className = toString.call(a), - otherClass = toString.call(b); + var valClass = toString.call(value), + othClass = toString.call(other); - if (className != otherClass) { + if (valClass != othClass) { return false; } - switch (className) { + switch (valClass) { case boolClass: case dateClass: - return +a == +b; + return +value == +other; case numberClass: - return a != +a - ? b != +b - : (a == 0 ? (1 / a == 1 / b) : a == +b); + return value != +value + ? other != +other + : (value == 0 ? (1 / value == 1 / other) : value == +other); case regexpClass: case stringClass: - return a == String(b); + return value == String(other); } - var isArr = className == arrayClass; + var isArr = valClass == arrayClass; if (!isArr) { - var aWrapped = a instanceof lodash, - bWrapped = b instanceof lodash; + var valWrapped = value instanceof lodash, + othWrapped = other instanceof lodash; - if (aWrapped || bWrapped) { - return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, stackA, stackB); + if (valWrapped || othWrapped) { + return baseIsEqual(valWrapped ? value.__wrapped__ : value, othWrapped ? other.__wrapped__ : other, stackA, stackB); } - if (className != objectClass) { + if (valClass != objectClass) { return false; } - var ownCtorA = hasOwnProperty.call(a, 'constructor'), - ownCtorB = hasOwnProperty.call(b, 'constructor'); + var hasValCtor = hasOwnProperty.call(value, 'constructor'), + hasOthCtor = hasOwnProperty.call(other, 'constructor'); - if (ownCtorA !== ownCtorB) { + if (hasValCtor !== hasOthCtor) { return false; } - if (!ownCtorA) { - var ctorA = a.constructor, - ctorB = b.constructor; + if (!hasValCtor) { + var valCtor = value.constructor, + othCtor = other.constructor; - if (ctorA != ctorB && - !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && - ('constructor' in a && 'constructor' in b) + if (valCtor != othCtor && + !(isFunction(valCtor) && valCtor instanceof valCtor && isFunction(othCtor) && othCtor instanceof othCtor) && + ('constructor' in value && 'constructor' in other) ) { return false; } @@ -842,39 +842,39 @@ var length = stackA.length; while (length--) { - if (stackA[length] == a) { - return stackB[length] == b; + if (stackA[length] == value) { + return stackB[length] == other; } } var result = true, size = 0; - stackA.push(a); - stackB.push(b); + stackA.push(value); + stackB.push(other); if (isArr) { - size = b.length; - result = size == a.length; + size = other.length; + result = size == value.length; if (result) { while (size--) { - if (!(result = baseIsEqual(a[size], b[size], stackA, stackB))) { + if (!(result = baseIsEqual(value[size], other[size], stackA, stackB))) { break; } } } } else { - baseForIn(b, function(value, key, b) { - if (hasOwnProperty.call(b, key)) { + baseForIn(other, function(othValue, key, other) { + if (hasOwnProperty.call(other, key)) { size++; - return !(result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, stackA, stackB)) && breakIndicator; + return !(result = hasOwnProperty.call(value, key) && baseIsEqual(value[key], othValue, stackA, stackB)) && breakIndicator; } }); if (result) { - baseForIn(a, function(value, key, a) { - if (hasOwnProperty.call(a, key)) { + baseForIn(value, function(valValue, key, value) { + if (hasOwnProperty.call(value, key)) { return !(result = --size > -1) && breakIndicator; } }); diff --git a/lodash.js b/lodash.js index 3e174015c..7c7f4720b 100644 --- a/lodash.js +++ b/lodash.js @@ -1135,8 +1135,8 @@ stackB.push(result); // recursively populate clone (susceptible to call stack limits) - (isArr ? baseEach : baseForOwn)(value, function(objValue, key) { - result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); + (isArr ? baseEach : baseForOwn)(value, function(valValue, key) { + result[key] = baseClone(valValue, isDeep, callback, stackA, stackB); }); return result; @@ -1557,84 +1557,91 @@ * @param {Array} [stackB=[]] Tracks traversed `other` objects. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. */ - function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { + function baseIsEqual(value, other, callback, isWhere, stackA, stackB) { if (callback) { - var result = callback(a, b); + var result = callback(value, other); if (typeof result != 'undefined') { return !!result; } } // exit early for identical values - if (a === b) { + if (value === other) { // treat `+0` vs. `-0` as not equal - return a !== 0 || (1 / a == 1 / b); + return value !== 0 || (1 / value == 1 / other); } - var type = typeof a, - otherType = typeof b; + var valType = typeof value, + othType = typeof other; // exit early for unlike primitive values - if (a === a && (a == null || b == null || - (type != 'function' && type != 'object' && otherType != 'function' && otherType != 'object'))) { + if (value === value && (value == null || other == null || + (valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object'))) { return false; } // compare [[Class]] names - var className = toString.call(a), - otherClass = toString.call(b); + var valClass = toString.call(value), + othClass = toString.call(other); - if (className == argsClass) { - className = objectClass; + if (valClass == argsClass) { + valClass = objectClass; } - if (otherClass == argsClass) { - otherClass = objectClass; + if (othClass == argsClass) { + othClass = objectClass; } - if (className != otherClass) { + if (valClass != othClass) { return false; } - switch (className) { + switch (valClass) { case boolClass: case dateClass: // coerce dates and booleans to numbers, dates to milliseconds and booleans // to `1` or `0` treating invalid dates coerced to `NaN` as not equal - return +a == +b; + return +value == +other; case numberClass: // treat `NaN` vs. `NaN` as equal - return (a != +a) - ? b != +b + return (value != +value) + ? other != +other // but treat `-0` vs. `+0` as not equal - : (a == 0 ? (1 / a == 1 / b) : a == +b); + : (value == 0 ? (1 / value == 1 / other) : value == +other); case regexpClass: case stringClass: // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) // treat string primitives and their corresponding object instances as equal - return a == String(b); + return value == String(other); } - var isArr = className == arrayClass; + var isArr = valClass == arrayClass; if (!isArr) { // unwrap any `lodash` wrapped values - var aWrapped = hasOwnProperty.call(a, '__wrapped__'), - bWrapped = hasOwnProperty.call(b, '__wrapped__'); + var valWrapped = hasOwnProperty.call(value, '__wrapped__'), + othWrapped = hasOwnProperty.call(other, '__wrapped__'); - if (aWrapped || bWrapped) { - return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); + if (valWrapped || othWrapped) { + return baseIsEqual(valWrapped ? value.__wrapped__ : value, othWrapped ? other.__wrapped__ : other, callback, isWhere, stackA, stackB); } // exit for functions and DOM nodes - if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { + if (valClass != objectClass || (!support.nodeClass && (isNode(value) || isNode(other)))) { return false; } - // in older versions of Opera, `arguments` objects have `Array` constructors - var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, - ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; + var hasValCtor = hasOwnProperty.call(value, 'constructor'), + hasOthCtor = hasOwnProperty.call(other, 'constructor'); - // non `Object` object instances with different constructors are not equal - if (ctorA != ctorB && - !(hasOwnProperty.call(a, 'constructor') && hasOwnProperty.call(b, 'constructor')) && - !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && - ('constructor' in a && 'constructor' in b) - ) { + if (hasValCtor !== hasOthCtor) { return false; } + if (!hasValCtor) { + // in older versions of Opera, `arguments` objects have `Array` constructors + var valCtor = !support.argsObject && isArguments(value) ? Object : value.constructor, + othCtor = !support.argsObject && isArguments(other) ? Object : other.constructor; + + // non `Object` object instances with different constructors are not equal + if (valCtor != othCtor && + !(isFunction(valCtor) && valCtor instanceof valCtor && isFunction(othCtor) && othCtor instanceof othCtor) && + ('constructor' in value && 'constructor' in other) + ) { + return false; + } + } } // assume cyclic structures are equal // the algorithm for detecting cyclic structures is adapted from ES 5.1 @@ -1645,37 +1652,37 @@ var length = stackA.length; while (length--) { - if (stackA[length] == a) { - return stackB[length] == b; + if (stackA[length] == value) { + return stackB[length] == other; } } var size = 0; result = true; - // add `a` and `b` to the stack of traversed objects - stackA.push(a); - stackB.push(b); + // add `value` and `other` to the stack of traversed objects + stackA.push(value); + stackB.push(other); // recursively compare objects and arrays (susceptible to call stack limits) if (isArr) { // compare lengths to determine if a deep comparison is necessary - length = a.length; - size = b.length; + length = value.length; + size = other.length; result = size == length; if (result || isWhere) { // deep compare the contents, ignoring non-numeric properties while (size--) { var index = length, - value = b[size]; + othValue = other[size]; if (isWhere) { while (index--) { - if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { + if ((result = baseIsEqual(value[index], othValue, callback, isWhere, stackA, stackB))) { break; } } - } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { + } else if (!(result = baseIsEqual(value[size], othValue, callback, isWhere, stackA, stackB))) { break; } } @@ -1684,20 +1691,20 @@ else { // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` // which, in this case, is more costly - baseForIn(b, function(value, key, b) { - if (hasOwnProperty.call(b, key)) { + baseForIn(other, function(othValue, key, other) { + if (hasOwnProperty.call(other, key)) { // count the number of properties. size++; // deep compare each property value. - return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); + return (result = hasOwnProperty.call(value, key) && baseIsEqual(value[key], othValue, callback, isWhere, stackA, stackB)); } }); if (result && !isWhere) { // ensure both objects have the same number of properties - baseForIn(a, function(value, key, a) { - if (hasOwnProperty.call(a, key)) { - // `size` will be `-1` if `a` has more properties than `b` + baseForIn(value, function(valValue, key, value) { + if (hasOwnProperty.call(value, key)) { + // `size` will be `-1` if `value` has more properties than `other` return (result = --size > -1); } }); @@ -6184,12 +6191,12 @@ // treat `-0` vs. `+0` as not equal return value !== 0 || (1 / value == 1 / other); } - var vType = typeof value, - oType = typeof other; + var valType = typeof value, + othType = typeof other; // exit early for unlike primitive values if (value === value && (value == null || other == null || - (vType != 'function' && vType != 'object' && oType != 'function' && oType != 'object'))) { + (valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object'))) { return false; } }