mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-01 23:57:49 +00:00
Loosen _.matches to match objects with inherited properties. [closes #1067]
This commit is contained in:
@@ -2265,12 +2265,12 @@
|
||||
* @param {*} value The value to compare.
|
||||
* @param {*} other The other value to compare.
|
||||
* @param {Function} [customizer] The function to customize comparing values.
|
||||
* @param {boolean} [isWhere] Specify performing partial comparisons.
|
||||
* @param {boolean} [isLoose] Specify performing partial comparisons.
|
||||
* @param {Array} [stackA] Tracks traversed `value` objects.
|
||||
* @param {Array} [stackB] Tracks traversed `other` objects.
|
||||
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
||||
*/
|
||||
function baseIsEqual(value, other, customizer, isWhere, stackA, stackB) {
|
||||
function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
|
||||
// Exit early for identical values.
|
||||
if (value === other) {
|
||||
// Treat `+0` vs. `-0` as not equal.
|
||||
@@ -2285,7 +2285,7 @@
|
||||
// Return `false` unless both values are `NaN`.
|
||||
return value !== value && other !== other;
|
||||
}
|
||||
return baseIsEqualDeep(value, other, baseIsEqual, customizer, isWhere, stackA, stackB);
|
||||
return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2298,12 +2298,12 @@
|
||||
* @param {Object} other The other object to compare.
|
||||
* @param {Function} equalFunc The function to determine equivalents of values.
|
||||
* @param {Function} [customizer] The function to customize comparing objects.
|
||||
* @param {boolean} [isWhere] Specify performing partial comparisons.
|
||||
* @param {boolean} [isLoose] Specify performing partial comparisons.
|
||||
* @param {Array} [stackA=[]] Tracks traversed `value` objects.
|
||||
* @param {Array} [stackB=[]] Tracks traversed `other` objects.
|
||||
* @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, isLoose, stackA, stackB) {
|
||||
var objIsArr = isArray(object),
|
||||
othIsArr = isArray(other),
|
||||
objTag = arrayTag,
|
||||
@@ -2325,21 +2325,27 @@
|
||||
othIsArr = isTypedArray(other);
|
||||
}
|
||||
}
|
||||
var objIsObj = objTag == objectTag && !isHostObject(object),
|
||||
var objIsObj = (objTag == objectTag || (isLoose && objTag == funcTag)) && !isHostObject(object),
|
||||
othIsObj = othTag == objectTag && !isHostObject(other),
|
||||
isSameTag = objTag == othTag;
|
||||
|
||||
if (isSameTag && !(objIsArr || objIsObj)) {
|
||||
return equalByTag(object, other, objTag);
|
||||
}
|
||||
var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
|
||||
othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
|
||||
if (isLoose) {
|
||||
if (!isSameTag && !(objIsObj && othIsObj)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
|
||||
othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
|
||||
|
||||
if (valWrapped || othWrapped) {
|
||||
return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isWhere, stackA, stackB);
|
||||
}
|
||||
if (!isSameTag) {
|
||||
return false;
|
||||
if (valWrapped || othWrapped) {
|
||||
return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
|
||||
}
|
||||
if (!isSameTag) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Assume cyclic values are equal.
|
||||
// For more information on detecting circular references see https://es5.github.io/#JO.
|
||||
@@ -2356,7 +2362,7 @@
|
||||
stackA.push(object);
|
||||
stackB.push(other);
|
||||
|
||||
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isWhere, stackA, stackB);
|
||||
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
|
||||
|
||||
stackA.pop();
|
||||
stackB.pop();
|
||||
@@ -2387,7 +2393,7 @@
|
||||
while (++index < length) {
|
||||
if ((noCustomizer && strictCompareFlags[index])
|
||||
? values[index] !== object[props[index]]
|
||||
: !hasOwnProperty.call(object, props[index])
|
||||
: !(props[index] in object)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@@ -2396,7 +2402,7 @@
|
||||
while (++index < length) {
|
||||
var key = props[index];
|
||||
if (noCustomizer && strictCompareFlags[index]) {
|
||||
var result = hasOwnProperty.call(object, key);
|
||||
var result = key in object;
|
||||
} else {
|
||||
var objValue = object[key],
|
||||
srcValue = values[index];
|
||||
@@ -2447,7 +2453,7 @@
|
||||
|
||||
if (isStrictComparable(value)) {
|
||||
return function(object) {
|
||||
return object != null && object[key] === value && hasOwnProperty.call(object, key);
|
||||
return object != null && object[key] === value && key in object;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2476,7 +2482,7 @@
|
||||
function baseMatchesProperty(key, value) {
|
||||
if (isStrictComparable(value)) {
|
||||
return function(object) {
|
||||
return object != null && object[key] === value;
|
||||
return object != null && object[key] === value && key in object;
|
||||
};
|
||||
}
|
||||
return function(object) {
|
||||
@@ -3771,18 +3777,18 @@
|
||||
* @param {Array} other The other array to compare.
|
||||
* @param {Function} equalFunc The function to determine equivalents of values.
|
||||
* @param {Function} [customizer] The function to customize comparing arrays.
|
||||
* @param {boolean} [isWhere] Specify performing partial comparisons.
|
||||
* @param {boolean} [isLoose] Specify performing partial comparisons.
|
||||
* @param {Array} [stackA] Tracks traversed `value` objects.
|
||||
* @param {Array} [stackB] Tracks traversed `other` objects.
|
||||
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
|
||||
*/
|
||||
function equalArrays(array, other, equalFunc, customizer, isWhere, stackA, stackB) {
|
||||
function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
|
||||
var index = -1,
|
||||
arrLength = array.length,
|
||||
othLength = other.length,
|
||||
result = true;
|
||||
|
||||
if (arrLength != othLength && !(isWhere && othLength > arrLength)) {
|
||||
if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
|
||||
return false;
|
||||
}
|
||||
// Deep compare the contents, ignoring non-numeric properties.
|
||||
@@ -3792,23 +3798,23 @@
|
||||
|
||||
result = undefined;
|
||||
if (customizer) {
|
||||
result = isWhere
|
||||
result = isLoose
|
||||
? customizer(othValue, arrValue, index)
|
||||
: customizer(arrValue, othValue, index);
|
||||
}
|
||||
if (typeof result == 'undefined') {
|
||||
// Recursively compare arrays (susceptible to call stack limits).
|
||||
if (isWhere) {
|
||||
if (isLoose) {
|
||||
var othIndex = othLength;
|
||||
while (othIndex--) {
|
||||
othValue = other[othIndex];
|
||||
result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB);
|
||||
result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB);
|
||||
result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3864,18 +3870,18 @@
|
||||
* @param {Object} other The other object to compare.
|
||||
* @param {Function} equalFunc The function to determine equivalents of values.
|
||||
* @param {Function} [customizer] The function to customize comparing values.
|
||||
* @param {boolean} [isWhere] Specify performing partial comparisons.
|
||||
* @param {boolean} [isLoose] Specify performing partial comparisons.
|
||||
* @param {Array} [stackA] Tracks traversed `value` objects.
|
||||
* @param {Array} [stackB] Tracks traversed `other` objects.
|
||||
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
||||
*/
|
||||
function equalObjects(object, other, equalFunc, customizer, isWhere, stackA, stackB) {
|
||||
function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
|
||||
var objProps = keys(object),
|
||||
objLength = objProps.length,
|
||||
othProps = keys(other),
|
||||
othLength = othProps.length;
|
||||
|
||||
if (objLength != othLength && !isWhere) {
|
||||
if (objLength != othLength && !isLoose) {
|
||||
return false;
|
||||
}
|
||||
var hasCtor,
|
||||
@@ -3883,7 +3889,7 @@
|
||||
|
||||
while (++index < objLength) {
|
||||
var key = objProps[index],
|
||||
result = hasOwnProperty.call(other, key);
|
||||
result = isLoose ? key in other : hasOwnProperty.call(other, key);
|
||||
|
||||
if (result) {
|
||||
var objValue = object[key],
|
||||
@@ -3891,13 +3897,13 @@
|
||||
|
||||
result = undefined;
|
||||
if (customizer) {
|
||||
result = isWhere
|
||||
result = isLoose
|
||||
? customizer(othValue, objValue, key)
|
||||
: customizer(objValue, othValue, key);
|
||||
}
|
||||
if (typeof result == 'undefined') {
|
||||
// Recursively compare objects (susceptible to call stack limits).
|
||||
result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isWhere, stackA, stackB);
|
||||
result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB);
|
||||
}
|
||||
}
|
||||
if (!result) {
|
||||
@@ -3905,7 +3911,7 @@
|
||||
}
|
||||
hasCtor || (hasCtor = key == 'constructor');
|
||||
}
|
||||
if (!hasCtor) {
|
||||
if (!hasCtor && !isLoose) {
|
||||
var objCtor = object.constructor,
|
||||
othCtor = other.constructor;
|
||||
|
||||
@@ -8715,7 +8721,7 @@
|
||||
value = source[key];
|
||||
|
||||
if (isStrictComparable(value)) {
|
||||
return object != null && value === object[key] && hasOwnProperty.call(object, key);
|
||||
return object != null && value === object[key] && key in object;
|
||||
}
|
||||
}
|
||||
var values = Array(length),
|
||||
|
||||
@@ -9634,7 +9634,7 @@
|
||||
objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
|
||||
actual = _.map(objects, matches);
|
||||
|
||||
deepEqual(actual, [true, false, true]);
|
||||
deepEqual(actual, [false, false, true]);
|
||||
|
||||
matches = _.matchesProperty('a', { 'b': undefined });
|
||||
objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 1 } }, { 'a': { 'a': 1, 'b': undefined } }];
|
||||
|
||||
Reference in New Issue
Block a user