From 225c8871f90e4a6ec9465ce40016a504eba9b6cf Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Tue, 8 Jul 2014 09:33:27 -0700 Subject: [PATCH] Avoid changes to `object` affecting the result of a match function. --- lodash.js | 20 ++++++++++++-------- test/test.js | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/lodash.js b/lodash.js index caab4d048..41bc2819a 100644 --- a/lodash.js +++ b/lodash.js @@ -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; } } diff --git a/test/test.js b/test/test.js index a929dfbf3..1f66af8a3 100644 --- a/test/test.js +++ b/test/test.js @@ -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));