Avoid changes to object affecting the result of a match function.

This commit is contained in:
John-David Dalton
2014-07-08 09:33:27 -07:00
parent d0333134d5
commit 225c8871f9
2 changed files with 28 additions and 8 deletions

View File

@@ -8524,14 +8524,17 @@
* // => { 'name': 'barney', 'age': 36 }
*/
function matches(source) {
var props = keys(source),
propsLength = props.length,
key = props[0],
value = propsLength && source[key];
var keyVals = pairs(source),
keyValsLength = keyVals.length;
if (keyValsLength) {
var keyVal = keyVals[0],
key = keyVal[0],
value = keyVal[1];
}
// fast path the common case of providing an object with a single
// property containing a primitive value
if (propsLength == 1 && value === value && !isObject(value)) {
if (keyValsLength == 1 && value === value && !isObject(value)) {
return function(object) {
if (object == null) {
return false;
@@ -8542,14 +8545,15 @@
};
}
return function(object) {
var length = propsLength;
var length = keyValsLength;
if (length && object == null) {
return false;
}
while (length--) {
var key = props[length];
keyVal = keyVals[length];
key = keyVal[0];
if (!(hasOwnProperty.call(object, key) &&
baseIsEqual(source[key], object[key], null, true))) {
baseIsEqual(keyVal[1], object[key], null, true))) {
return false;
}
}

View File

@@ -6689,6 +6689,22 @@
strictEqual(matches(otherObject), false);
});
test('should not change match behavior if `source` is augmented', 6, function() {
_.each([{ 'a': 1 }, { 'a': 1, 'b': 2 }], function(source) {
var object = _.clone(source),
matches = _.matches(source);
strictEqual(matches(object), true);
source.a = 2;
source.b = 1;
source.c = 3;
strictEqual(matches(object), true);
strictEqual(matches(source), false);
});
});
test('should return `true` when comparing an empty `source`', 1, function() {
var object = { 'a': 1 },
expected = _.map(empties, _.constant(true));