mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-09 18:37:50 +00:00
Ensure _.match deep comparison isn't affected by changes to source objects.
This commit is contained in:
48
lodash.js
48
lodash.js
@@ -8525,36 +8525,32 @@
|
|||||||
* // => { 'name': 'barney', 'age': 36 }
|
* // => { 'name': 'barney', 'age': 36 }
|
||||||
*/
|
*/
|
||||||
function matches(source) {
|
function matches(source) {
|
||||||
var keyVals = pairs(source),
|
var props = keys(source),
|
||||||
keyValsLength = keyVals.length;
|
length = props.length,
|
||||||
|
index = length,
|
||||||
|
modes = Array(length),
|
||||||
|
vals = Array(length);
|
||||||
|
|
||||||
if (keyValsLength) {
|
while (index--) {
|
||||||
var keyVal = keyVals[0],
|
var value = source[props[index]],
|
||||||
key = keyVal[0],
|
isDeep = value !== value || (value === 0 && 1 / value < 0) || isObject(value);
|
||||||
value = keyVal[1];
|
|
||||||
}
|
modes[index] = isDeep;
|
||||||
// fast path the common case of providing an object with a single
|
vals[index] = isDeep ? baseClone(value, isDeep) : value;
|
||||||
// property containing a primitive value
|
|
||||||
if (keyValsLength == 1 && value === value && !isObject(value)) {
|
|
||||||
return function(object) {
|
|
||||||
if (object == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// treat `-0` vs. `+0` as not equal
|
|
||||||
var other = object[key];
|
|
||||||
return value === other && (value !== 0 || (1 / value == 1 / other)) && hasOwnProperty.call(object, key);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return function(object) {
|
return function(object) {
|
||||||
var length = keyValsLength;
|
index = length;
|
||||||
if (length && object == null) {
|
if (object == null) {
|
||||||
return false;
|
return !index;
|
||||||
}
|
}
|
||||||
while (length--) {
|
while (index--) {
|
||||||
keyVal = keyVals[length];
|
if (modes[index] ? !hasOwnProperty.call(object, props[index]) : vals[index] !== object[props[index]]) {
|
||||||
key = keyVal[0];
|
return false;
|
||||||
if (!(hasOwnProperty.call(object, key) &&
|
}
|
||||||
baseIsEqual(keyVal[1], object[key], null, true))) {
|
}
|
||||||
|
index = length;
|
||||||
|
while (index--) {
|
||||||
|
if (modes[index] ? !baseIsEqual(vals[index], object[props[index]], null, true) : !hasOwnProperty.call(object, props[index])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
31
test/test.js
31
test/test.js
@@ -6681,8 +6681,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should compare a variety of `source` object values', 2, function() {
|
test('should compare a variety of `source` object values', 2, function() {
|
||||||
var object = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
|
var object = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
|
||||||
otherObject = _.assign({}, object, { 'a': false, 'c': 3, 'f': { 'g': '6' } }),
|
otherObject = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
|
||||||
matches = _.matches(object);
|
matches = _.matches(object);
|
||||||
|
|
||||||
strictEqual(matches(object), true);
|
strictEqual(matches(object), true);
|
||||||
@@ -6690,18 +6690,23 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should not change match behavior if `source` is augmented', 6, function() {
|
test('should not change match behavior if `source` is augmented', 6, function() {
|
||||||
_.each([{ 'a': 1 }, { 'a': 1, 'b': 2 }], function(source) {
|
_.each([{ 'a': 1, 'b': 2 }, { 'a': { 'b': 2, 'c': 3 } }], function(source, index) {
|
||||||
var object = _.clone(source),
|
var object = _.cloneDeep(source),
|
||||||
matches = _.matches(source);
|
matches = _.matches(source);
|
||||||
|
|
||||||
strictEqual(matches(object), true);
|
strictEqual(matches(object), true, 'a' + index);
|
||||||
|
|
||||||
source.a = 2;
|
if (index) {
|
||||||
source.b = 1;
|
source.a.b = 1;
|
||||||
source.c = 3;
|
source.a.c = 2;
|
||||||
|
source.a.d = 3;
|
||||||
strictEqual(matches(object), true);
|
} else {
|
||||||
strictEqual(matches(source), false);
|
source.a = 2;
|
||||||
|
source.b = 1;
|
||||||
|
source.c = 3;
|
||||||
|
}
|
||||||
|
strictEqual(matches(object), true, 'b' + index);
|
||||||
|
strictEqual(matches(source), false, 'c' + index);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -10801,8 +10806,8 @@
|
|||||||
'z': { 'a': 1, 'b': 2 }
|
'z': { 'a': 1, 'b': 2 }
|
||||||
};
|
};
|
||||||
|
|
||||||
var expected = [object.x, object.z],
|
var actual = _.where(object, { 'a': 1 }),
|
||||||
actual = _.where(object, { 'a': 1 });
|
expected = [object.x, object.z];
|
||||||
|
|
||||||
deepEqual(actual, expected);
|
deepEqual(actual, expected);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user