Skip to content

Commit 8bb4b5f

Browse files
committed
refactor(equalsFunction): divid internal implemenation
extract complex logic to named methods fixes angular#13957
1 parent c4e47e4 commit 8bb4b5f

File tree

1 file changed

+110
-32
lines changed

1 file changed

+110
-32
lines changed

src/Angular.js

+110-32
Original file line numberDiff line numberDiff line change
@@ -977,46 +977,124 @@ function shallowCopy(src, dst) {
977977
* @returns {boolean} True if arguments are equal.
978978
*/
979979
function equals(o1, o2) {
980-
if (o1 === o2) return true;
981-
if (o1 === null || o2 === null) return false;
982-
if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
983-
var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
984-
if (t1 == t2 && t1 == 'object') {
985-
if (isArray(o1)) {
986-
if (!isArray(o2)) return false;
987-
if ((length = o1.length) == o2.length) {
988-
for (key = 0; key < length; key++) {
989-
if (!equals(o1[key], o2[key])) return false;
990-
}
991-
return true;
980+
981+
if (areBothEqualValues(o1, o2)) {
982+
return true;
983+
}
984+
985+
if (isAnyOneHasValueEqualNull(o1, o2)) {
986+
return false;
987+
}
988+
if (areBothValuesEqualNaN(o1, o2)) {
989+
return true;
990+
}
991+
992+
if (areBothObjectsEqual(o1, o2)) {
993+
return true;
994+
}
995+
996+
return false;
997+
}
998+
999+
function areBothEqualValues(o1, o2) {
1000+
return (o1 === o2);
1001+
}
1002+
1003+
function isAnyOneHasValueEqualNull(o1, o2) {
1004+
return (o1 === null || o2 === null);
1005+
}
1006+
1007+
function areBothValuesEqualNaN(o1, o2) {
1008+
return (o1 !== o1 && o2 !== o2);
1009+
}
1010+
1011+
function areBothObjectsEqual(o1, o2) {
1012+
1013+
if (areBothObjectsEqualType(o1, o2)) {
1014+
var isO1ArrayType = isArray(o1);
1015+
var isO2ArrayType = isArray(o2);
1016+
if (isO1ArrayType || isO2ArrayType) {
1017+
if (isO2ArrayType && isO2ArrayType) {
1018+
return areBothArraysEqual(o1, o2)
9921019
}
993-
} else if (isDate(o1)) {
994-
if (!isDate(o2)) return false;
995-
return equals(o1.getTime(), o2.getTime());
996-
} else if (isRegExp(o1)) {
997-
if (!isRegExp(o2)) return false;
998-
return o1.toString() == o2.toString();
999-
} else {
1000-
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
1001-
isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
1002-
keySet = createMap();
1003-
for (key in o1) {
1004-
if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
1005-
if (!equals(o1[key], o2[key])) return false;
1006-
keySet[key] = true;
1020+
return false;
1021+
}
1022+
1023+
var isO1DateType = isDate(o1);
1024+
var isO2DateType = isDate(o2);
1025+
if (isO1DateType || isO2DateType) {
1026+
if (isO1DateType && isO2DateType) {
1027+
return areBothDatesEqual(o1, o2)
10071028
}
1008-
for (key in o2) {
1009-
if (!(key in keySet) &&
1010-
key.charAt(0) !== '$' &&
1011-
isDefined(o2[key]) &&
1012-
!isFunction(o2[key])) return false;
1029+
return false;
1030+
}
1031+
1032+
var isO1RegExpType = isRegExp(o1);
1033+
var isO2RegExpType = isRegExp(o1);
1034+
1035+
if (isO1RegExpType || isO2RegExpType) {
1036+
if (isO1RegExpType && isO2RegExpType) {
1037+
return areBothRegExpEqual(o1, o2)
1038+
}
1039+
return false;
1040+
1041+
}
1042+
1043+
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
1044+
1045+
return areBothMapsEqual(o1, o2);
1046+
1047+
}
1048+
1049+
return false;
1050+
}
1051+
1052+
function areBothObjectsEqualType(o1, o2) {
1053+
var t1 = typeof o1;
1054+
var t2 = typeof o2;
1055+
1056+
return (t1 == t2 && t1 == 'object');
1057+
}
1058+
1059+
function areBothArraysEqual(o1, o2) {
1060+
var length, key;
1061+
1062+
if ((length = o1.length) == o2.length) {
1063+
for (key = 0; key < length; key++) {
1064+
if (!equals(o1[key], o2[key])) {
1065+
return false;
10131066
}
1014-
return true;
10151067
}
1068+
return true;
10161069
}
1070+
10171071
return false;
10181072
}
10191073

1074+
function areBothDatesEqual(o1, o2) {
1075+
return equals(o1.getTime(), o2.getTime());
1076+
}
1077+
1078+
function areBothRegExpEqual(o1, o2) {
1079+
return (o1.toString() == o2.toString());
1080+
}
1081+
1082+
function areBothMapsEqual() {
1083+
var keySet, key;
1084+
keySet = createMap();
1085+
for (key in o1) {
1086+
if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
1087+
if (!equals(o1[key], o2[key])) return false;
1088+
keySet[key] = true;
1089+
}
1090+
for (key in o2) {
1091+
if (!(key in keySet) &&
1092+
key.charAt(0) !== '$' &&
1093+
isDefined(o2[key]) && !isFunction(o2[key])) return false;
1094+
}
1095+
return true;
1096+
}
1097+
10201098
var csp = function() {
10211099
if (!isDefined(csp.rules)) {
10221100

0 commit comments

Comments
 (0)