* @ngdoc function * @name angular.equals * @module ng * @kind function * * @description * Determines if two objects or two values are equivalent. Supports value types, regular * expressions, arrays and objects. * * Two objects or values are considered equivalent if at least one of the follo
(o1, o2)
| 1181 | </example> |
| 1182 | */ |
| 1183 | function equals(o1, o2) { |
| 1184 | if (o1 === o2) return true; |
| 1185 | if (o1 === null || o2 === null) return false; |
| 1186 | // eslint-disable-next-line no-self-compare |
| 1187 | if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN |
| 1188 | var t1 = typeof o1, t2 = typeof o2, length, key, keySet; |
| 1189 | if (t1 === t2 && t1 === 'object') { |
| 1190 | if (isArray(o1)) { |
| 1191 | if (!isArray(o2)) return false; |
| 1192 | if ((length = o1.length) === o2.length) { |
| 1193 | for (key = 0; key < length; key++) { |
| 1194 | if (!equals(o1[key], o2[key])) return false; |
| 1195 | } |
| 1196 | return true; |
| 1197 | } |
| 1198 | } else if (isDate(o1)) { |
| 1199 | if (!isDate(o2)) return false; |
| 1200 | return simpleCompare(o1.getTime(), o2.getTime()); |
| 1201 | } else if (isRegExp(o1)) { |
| 1202 | if (!isRegExp(o2)) return false; |
| 1203 | return o1.toString() === o2.toString(); |
| 1204 | } else { |
| 1205 | if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || |
| 1206 | isArray(o2) || isDate(o2) || isRegExp(o2)) return false; |
| 1207 | keySet = createMap(); |
| 1208 | for (key in o1) { |
| 1209 | if (key.charAt(0) === '$' || isFunction(o1[key])) continue; |
| 1210 | if (!equals(o1[key], o2[key])) return false; |
| 1211 | keySet[key] = true; |
| 1212 | } |
| 1213 | for (key in o2) { |
| 1214 | if (!(key in keySet) && |
| 1215 | key.charAt(0) !== '$' && |
| 1216 | isDefined(o2[key]) && |
| 1217 | !isFunction(o2[key])) return false; |
| 1218 | } |
| 1219 | return true; |
| 1220 | } |
| 1221 | } |
| 1222 | return false; |
| 1223 | } |
| 1224 | |
| 1225 | var csp = function() { |
| 1226 | if (!isDefined(csp.rules)) { |
no test coverage detected