* @ngdoc function * @name angular.equals * @function * * @description * Determines if two objects or two values are equivalent. Supports value types, arrays and * objects. * * Two objects or values are considered equivalent if at least one of the following is true: * * * Both objects or va
(o1, o2)
| 647 | * @returns {boolean} True if arguments are equal. |
| 648 | */ |
| 649 | function equals(o1, o2) { |
| 650 | if (o1 === o2) return true; |
| 651 | if (o1 === null || o2 === null) return false; |
| 652 | if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN |
| 653 | var t1 = typeof o1, t2 = typeof o2, length, key, keySet; |
| 654 | if (t1 == t2) { |
| 655 | if (t1 == 'object') { |
| 656 | if (isArray(o1)) { |
| 657 | if ((length = o1.length) == o2.length) { |
| 658 | for(key=0; key<length; key++) { |
| 659 | if (!equals(o1[key], o2[key])) return false; |
| 660 | } |
| 661 | return true; |
| 662 | } |
| 663 | } else if (isDate(o1)) { |
| 664 | return isDate(o2) && o1.getTime() == o2.getTime(); |
| 665 | } else { |
| 666 | if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false; |
| 667 | keySet = {}; |
| 668 | for(key in o1) { |
| 669 | if (key.charAt(0) === '$' || isFunction(o1[key])) continue; |
| 670 | if (!equals(o1[key], o2[key])) return false; |
| 671 | keySet[key] = true; |
| 672 | } |
| 673 | for(key in o2) { |
| 674 | if (!keySet[key] && |
| 675 | key.charAt(0) !== '$' && |
| 676 | o2[key] !== undefined && |
| 677 | !isFunction(o2[key])) return false; |
| 678 | } |
| 679 | return true; |
| 680 | } |
| 681 | } |
| 682 | } |
| 683 | return false; |
| 684 | } |
| 685 | |
| 686 | |
| 687 | function concat(array1, array2, index) { |
no test coverage detected