AbstractRelationalComparison.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. 'use strict';
  2. var GetIntrinsic = require('get-intrinsic');
  3. var $Number = GetIntrinsic('%Number%');
  4. var $TypeError = require('es-errors/type');
  5. var $isNaN = require('../helpers/isNaN');
  6. var $isFinite = require('../helpers/isFinite');
  7. var isPrefixOf = require('../helpers/isPrefixOf');
  8. var ToNumber = require('./ToNumber');
  9. var ToPrimitive = require('./ToPrimitive');
  10. // https://262.ecma-international.org/5.1/#sec-11.8.5
  11. // eslint-disable-next-line max-statements
  12. module.exports = function AbstractRelationalComparison(x, y, LeftFirst) {
  13. if (typeof LeftFirst !== 'boolean') {
  14. throw new $TypeError('Assertion failed: LeftFirst argument must be a Boolean');
  15. }
  16. var px;
  17. var py;
  18. if (LeftFirst) {
  19. px = ToPrimitive(x, $Number);
  20. py = ToPrimitive(y, $Number);
  21. } else {
  22. py = ToPrimitive(y, $Number);
  23. px = ToPrimitive(x, $Number);
  24. }
  25. var bothStrings = typeof px === 'string' && typeof py === 'string';
  26. if (!bothStrings) {
  27. var nx = ToNumber(px);
  28. var ny = ToNumber(py);
  29. if ($isNaN(nx) || $isNaN(ny)) {
  30. return undefined;
  31. }
  32. if ($isFinite(nx) && $isFinite(ny) && nx === ny) {
  33. return false;
  34. }
  35. if (nx === Infinity) {
  36. return false;
  37. }
  38. if (ny === Infinity) {
  39. return true;
  40. }
  41. if (ny === -Infinity) {
  42. return false;
  43. }
  44. if (nx === -Infinity) {
  45. return true;
  46. }
  47. return nx < ny; // by now, these are both nonzero, finite, and not equal
  48. }
  49. if (isPrefixOf(py, px)) {
  50. return false;
  51. }
  52. if (isPrefixOf(px, py)) {
  53. return true;
  54. }
  55. return px < py; // both strings, neither a prefix of the other. shortcut for steps c-f
  56. };