mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-08 18:17:48 +00:00
Add fast path for objects with a single primitive value back to _.matches and add isStrictComparable helper to reduce _.matches and _.isEqual.
This commit is contained in:
61
lodash.js
61
lodash.js
@@ -2893,6 +2893,18 @@
|
|||||||
: (value && type == 'object' && reHostCtor.test(toString.call(value))) || false;
|
: (value && type == 'object' && reHostCtor.test(toString.call(value))) || false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {*} value The value to check.
|
||||||
|
* @returns {boolean} Returns `true` if `value` if suitable for strict
|
||||||
|
* equality comparisons, else `false`.
|
||||||
|
*/
|
||||||
|
function isStrictComparable(value) {
|
||||||
|
return value === value && (value === 0 ? (1 / value > 0) : !isObject(value));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a clone of the given array buffer.
|
* Creates a clone of the given array buffer.
|
||||||
*
|
*
|
||||||
@@ -6963,23 +6975,9 @@
|
|||||||
*/
|
*/
|
||||||
function isEqual(value, other, customizer, thisArg) {
|
function isEqual(value, other, customizer, thisArg) {
|
||||||
customizer = typeof customizer == 'function' && baseCallback(customizer, thisArg, 3);
|
customizer = typeof customizer == 'function' && baseCallback(customizer, thisArg, 3);
|
||||||
|
return (!customizer && isStrictComparable(value) && isStrictComparable(other))
|
||||||
if (!customizer) {
|
? value === other
|
||||||
// exit early for identical values
|
: baseIsEqual(value, other, customizer);
|
||||||
if (value === other) {
|
|
||||||
// treat `-0` vs. `+0` as not equal
|
|
||||||
return value !== 0 || (1 / value == 1 / other);
|
|
||||||
}
|
|
||||||
var valType = typeof value,
|
|
||||||
othType = typeof other;
|
|
||||||
|
|
||||||
// exit early for unlike primitive values
|
|
||||||
if (value === value && (value == null || other == null ||
|
|
||||||
(valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object'))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return baseIsEqual(value, other, customizer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -8542,17 +8540,28 @@
|
|||||||
*/
|
*/
|
||||||
function matches(source) {
|
function matches(source) {
|
||||||
var props = keys(source),
|
var props = keys(source),
|
||||||
length = props.length,
|
length = props.length;
|
||||||
index = length,
|
|
||||||
modes = Array(length),
|
if (length == 1) {
|
||||||
|
var key = props[0],
|
||||||
|
value = source[key];
|
||||||
|
|
||||||
|
if (isStrictComparable(value)) {
|
||||||
|
return function(object) {
|
||||||
|
return object != null && value === object[key] && hasOwnProperty.call(object, key);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var index = length,
|
||||||
|
flags = Array(length),
|
||||||
vals = Array(length);
|
vals = Array(length);
|
||||||
|
|
||||||
while (index--) {
|
while (index--) {
|
||||||
var value = source[props[index]],
|
value = source[props[index]];
|
||||||
isDeep = value !== value || (value === 0 && 1 / value < 0) || isObject(value);
|
var isStrict = isStrictComparable(value);
|
||||||
|
|
||||||
modes[index] = isDeep;
|
flags[index] = isStrict;
|
||||||
vals[index] = isDeep ? baseClone(value, isDeep) : value;
|
vals[index] = isStrict ? value : baseClone(value, false);
|
||||||
}
|
}
|
||||||
return function(object) {
|
return function(object) {
|
||||||
index = length;
|
index = length;
|
||||||
@@ -8560,13 +8569,13 @@
|
|||||||
return !index;
|
return !index;
|
||||||
}
|
}
|
||||||
while (index--) {
|
while (index--) {
|
||||||
if (modes[index] ? !hasOwnProperty.call(object, props[index]) : vals[index] !== object[props[index]]) {
|
if (flags[index] ? vals[index] !== object[props[index]] : !hasOwnProperty.call(object, props[index])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
index = length;
|
index = length;
|
||||||
while (index--) {
|
while (index--) {
|
||||||
if (modes[index] ? !baseIsEqual(vals[index], object[props[index]], null, true) : !hasOwnProperty.call(object, props[index])) {
|
if (flags[index] ? !hasOwnProperty.call(object, props[index]) : !baseIsEqual(vals[index], object[props[index]], null, true)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
test/test.js
18
test/test.js
@@ -6721,24 +6721,24 @@
|
|||||||
strictEqual(matches(otherObject), false);
|
strictEqual(matches(otherObject), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not change match behavior if `source` is augmented', 6, function() {
|
test('should not change match behavior if `source` is augmented', 9, function() {
|
||||||
_.each([{ 'a': 1, 'b': 2 }, { 'a': { 'b': 2, 'c': 3 } }], function(source, index) {
|
_.each([{ 'a': { 'b': 2, 'c': 3 } }, { 'a': 1, 'b': 2 }, { 'a': 1 }], function(source, index) {
|
||||||
var object = _.cloneDeep(source),
|
var object = _.cloneDeep(source),
|
||||||
matches = _.matches(source);
|
matches = _.matches(source);
|
||||||
|
|
||||||
strictEqual(matches(object), true, 'a' + index);
|
strictEqual(matches(object), true);
|
||||||
|
|
||||||
if (index) {
|
if (index) {
|
||||||
source.a.b = 1;
|
|
||||||
source.a.c = 2;
|
|
||||||
source.a.d = 3;
|
|
||||||
} else {
|
|
||||||
source.a = 2;
|
source.a = 2;
|
||||||
source.b = 1;
|
source.b = 1;
|
||||||
source.c = 3;
|
source.c = 3;
|
||||||
|
} else {
|
||||||
|
source.a.b = 1;
|
||||||
|
source.a.c = 2;
|
||||||
|
source.a.d = 3;
|
||||||
}
|
}
|
||||||
strictEqual(matches(object), true, 'b' + index);
|
strictEqual(matches(object), true);
|
||||||
strictEqual(matches(source), false, 'c' + index);
|
strictEqual(matches(source), false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user