* @ngdoc function * @name angular.equals * @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 following is true: * *
(o1, o2)
| 886 | * @returns {boolean} True if arguments are equal. |
| 887 | */ |
| 888 | function equals(o1, o2) { |
| 889 | if (o1 === o2) return true; |
| 890 | if (o1 === null || o2 === null) return false; |
| 891 | if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN |
| 892 | var t1 = typeof o1, t2 = typeof o2, length, key, keySet; |
| 893 | if (t1 == t2) { |
| 894 | if (t1 == 'object') { |
| 895 | if (isArray(o1)) { |
| 896 | if (!isArray(o2)) return false; |
| 897 | if ((length = o1.length) == o2.length) { |
| 898 | for(key=0; key<length; key++) { |
| 899 | if (!equals(o1[key], o2[key])) return false; |
| 900 | } |
| 901 | return true; |
| 902 | } |
| 903 | } else if (isDate(o1)) { |
| 904 | return isDate(o2) && o1.getTime() == o2.getTime(); |
| 905 | } else if (isRegExp(o1) && isRegExp(o2)) { |
| 906 | return o1.toString() == o2.toString(); |
| 907 | } else { |
| 908 | if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2)) return false; |
| 909 | keySet = {}; |
| 910 | for(key in o1) { |
| 911 | if (key.charAt(0) === '$' || isFunction(o1[key])) continue; |
| 912 | if (!equals(o1[key], o2[key])) return false; |
| 913 | keySet[key] = true; |
| 914 | } |
| 915 | for(key in o2) { |
| 916 | if (!keySet.hasOwnProperty(key) && |
| 917 | key.charAt(0) !== '$' && |
| 918 | o2[key] !== undefined && |
| 919 | !isFunction(o2[key])) return false; |
| 920 | } |
| 921 | return true; |
| 922 | } |
| 923 | } |
| 924 | } |
| 925 | return false; |
| 926 | } |
| 927 | |
| 928 | |
| 929 | function csp() { |
no test coverage detected
searching dependent graphs…