(a, b)
| 594 | } |
| 595 | |
| 596 | function innerEquiv(a, b) { |
| 597 | var i, pair; |
| 598 | |
| 599 | // We're done when there's nothing more to compare |
| 600 | if (arguments.length < 2) { |
| 601 | return true; |
| 602 | } |
| 603 | |
| 604 | // Clear the global pair queue and add the top-level values being compared |
| 605 | pairs = [{ a: a, b: b }]; |
| 606 | |
| 607 | for (i = 0; i < pairs.length; i++) { |
| 608 | pair = pairs[i]; |
| 609 | |
| 610 | // Perform type-specific comparison on any pairs that are not strictly |
| 611 | // equal. For container types, that comparison will postpone comparison |
| 612 | // of any sub-container pair to the end of the pair queue. This gives |
| 613 | // breadth-first search order. It also avoids the reprocessing of |
| 614 | // reference-equal siblings, cousins etc, which can have a significant speed |
| 615 | // impact when comparing a container of small objects each of which has a |
| 616 | // reference to the same (singleton) large object. |
| 617 | if (pair.a !== pair.b && !typeEquiv(pair.a, pair.b)) { |
| 618 | return false; |
| 619 | } |
| 620 | } |
| 621 | |
| 622 | // ...across all consecutive argument pairs |
| 623 | return arguments.length === 2 || innerEquiv.apply(this, [].slice.call(arguments, 1)); |
| 624 | } |
| 625 | |
| 626 | return function () { |
| 627 | var result = innerEquiv.apply(undefined, arguments); |
no test coverage detected