DEV Community

Clean Code Studio
Clean Code Studio

Posted on • Edited on

Compare Things In JavaScript [Explained in A Gross Amount of Detail]


Twitter Follow

Ever get stuck wondering if you need...

a == b

or

a === b

or

isLooselyEqual(a, b)

or

isStrictlyEqual(a, b)


I know I sure have.

Testing and Comparison Operations - the actual definitions.

This is content pulled directly from ECMAscript specifications(Not written by me). It defines specifically how comparisons/testing operations work to an almost grows amount of detail. Good reference to have if you're unsure whether you need two equal signs or one equal sign to check if two things are the same or different.


7.2.2 IsArray ( argument )


The abstract operation IsArray takes argument argument. It performs the following steps when called:

  1. 1. If Type(argument) is not Object, return false.
  2. 2. If argument is an Array exotic object, return true.
  3. 3. If argument is a Proxy exotic object, then
    1. a. If argument.[[ProxyHandler]] is null, throw a TypeError exception.
    2. b. Let target be argument.[[ProxyTarget]].
    3. c. Return ? IsArray(target).
  4. 4. Return false.

7.2.3 IsCallable ( argument )


The abstract operation IsCallable takes argument argument (an ECMAScript language value). It determines if argument is a callable function with a [[Call]] internal method. It performs the following steps when called:

  1. 1. If Type(argument) is not Object, return false.
  2. 2. If argument has a [[Call]] internal method, return true.
  3. 3. Return false.

7.2.4 IsConstructor ( argument )


The abstract operation IsConstructor takes argument argument (an ECMAScript language value). It determines if argument is a function object with a [[Construct]] internal method. It performs the following steps when called:

  1. 1. If Type(argument) is not Object, return false.
  2. 2. If argument has a [[Construct]] internal method, return true.
  3. 3. Return false.

7.2.5 IsExtensible ( O )


The abstract operation IsExtensible takes argument O (an Object). It returns a completion record which, if its [[Type]] is normal, has a [[Value]] which is a Boolean. It is used to determine whether additional properties can be added to O. It performs the following steps when called:

  1. 1. Assert: Type(O) is Object.
  2. 2. Return ? O.[[IsExtensible]]().

7.2.6 IsIntegralNumber ( argument )


The abstract operation IsIntegralNumber takes argument argument. It determines if argument is a finite integral Number value. It performs the following steps when called:

  1. 1. If Type(argument) is not Number, return false.
  2. 2. If argument is NaN, +∞𝔽, or -∞𝔽, return false.
  3. 3. If floor(abs((argument))) ≠ abs((argument)), return false.
  4. 4. Return true.

7.2.7 IsPropertyKey ( argument )


The abstract operation IsPropertyKey takes argument argument (an ECMAScript language value). It determines if argument is a value that may be used as a property key. It performs the following steps when called:

  1. 1. If Type(argument) is String, return true.
  2. 2. If Type(argument) is Symbol, return true.
  3. 3. Return false.

7.2.8 IsRegExp ( argument )


The abstract operation IsRegExp takes argument argument. It performs the following steps when called:

  1. 1. If Type(argument) is not Object, return false.
  2. 2. Let matcher be ? Get(argument, @@match).
  3. 3. If matcher is not undefined, return ! ToBoolean(matcher).
  4. 4. If argument has a [[RegExpMatcher]] internal slot, return true.
  5. 5. Return false.

7.2.9 IsStringPrefix ( p, q )


The abstract operation IsStringPrefix takes arguments p (a String) and q (a String). It determines if p is a prefix of q. It performs the following steps when called:

  1. 1. Assert: Type(p) is String.
  2. 2. Assert: Type(q) is String.
  3. 3. If q can be the string-concatenation of p and some other String r, return true. Otherwise, return false.
Note

Any String is a prefix of itself, because r may be the empty String.
Enter fullscreen mode Exit fullscreen mode

7.2.10 SameValue ( x, y )


The abstract operation SameValue takes arguments x (an ECMAScript language value) and y (an ECMAScript language value). It returns a completion record whose [[Type]] is normal and whose [[Value]] is a Boolean. It performs the following steps when called:

  1. 1. If Type(x) is different from Type(y), return false.
  2. 2. If Type(x) is Number or BigInt, then
    1. a. Return ! Type(x)::sameValue(x, y).
  3. 3. Return ! SameValueNonNumeric(x, y).
Note

This algorithm differs from the [IsStrictlyEqual](https://tc39.es/ecma262/#sec-isstrictlyequal) Algorithm in its treatment of signed zeroes and NaNs.
Enter fullscreen mode Exit fullscreen mode

7.2.11 SameValueZero ( x, y )


The abstract operation SameValueZero takes arguments x (an ECMAScript language value) and y (an ECMAScript language value). It returns a completion record whose [[Type]] is normal and whose [[Value]] is a Boolean. It performs the following steps when called:

  1. 1. If Type(x) is different from Type(y), return false.
  2. 2. If Type(x) is Number or BigInt, then
    1. a. Return ! Type(x)::sameValueZero(x, y).
  3. 3. Return ! SameValueNonNumeric(x, y).
Note

SameValueZero differs from [SameValue](https://tc39.es/ecma262/#sec-samevalue) only in its treatment of +0𝔽 and \-0𝔽.
Enter fullscreen mode Exit fullscreen mode

7.2.12 SameValueNonNumeric ( x, y )


The abstract operation SameValueNonNumeric takes arguments x (an ECMAScript language value) and y (an ECMAScript language value). It returns a completion record whose [[Type]] is normal and whose [[Value]] is a Boolean. It performs the following steps when called:

  1. 1. Assert: Type(x) is not Number or BigInt.
  2. 2. Assert: Type(x) is the same as Type(y).
  3. 3. If Type(x) is Undefined, return true.
  4. 4. If Type(x) is Null, return true.
  5. 5. If Type(x) is String, then
    1. a. If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return true; otherwise, return false.
  6. 6. If Type(x) is Boolean, then
    1. a. If x and y are both true or both false, return true; otherwise, return false.
  7. 7. If Type(x) is Symbol, then
    1. a. If x and y are both the same Symbol value, return true; otherwise, return false.
  8. 8. If x and y are the same Object value, return true. Otherwise, return false.

7.2.13 IsLessThan ( x, y, LeftFirst )


The abstract operation IsLessThan takes arguments x (an ECMAScript language value), y (an ECMAScript language value), and LeftFirst (a Boolean). It provides the semantics for the comparison x < y, returning true, false, or undefined (which indicates that at least one operand is NaN). The LeftFirst flag is used to control the order in which operations with potentially visible side-effects are performed upon x and y. It is necessary because ECMAScript specifies left to right evaluation of expressions. If LeftFirst is true, the x parameter corresponds to an expression that occurs to the left of the y parameter's corresponding expression. If LeftFirst is false, the reverse is the case and operations must be performed upon y before x. It performs the following steps when called:

  1. 1. If the LeftFirst flag is true, then
    1. a. Let px be ? ToPrimitive(x, number).
    2. b. Let py be ? ToPrimitive(y, number).
  2. 2. Else,
    1. a. NOTE: The order of evaluation needs to be reversed to preserve left to right evaluation.
    2. b. Let py be ? ToPrimitive(y, number).
    3. c. Let px be ? ToPrimitive(x, number).
  3. 3. If Type(px) is String and Type(py) is String, then
    1. a. If IsStringPrefix(py, px) is true, return false.
    2. b. If IsStringPrefix(px, py) is true, return true.
    3. c. Let k be the smallest non-negative integer such that the code unit at index k within px is different from the code unit at index k within py. (There must be such a k, for neither String is a prefix of the other.)
    4. d. Let m be the integer that is the numeric value of the code unit at index k within px.
    5. e. Let n be the integer that is the numeric value of the code unit at index k within py.
    6. f. If m < n, return true. Otherwise, return false.
  4. 4. Else,
    1. a. If Type(px) is BigInt and Type(py) is String, then
      1. i. Let ny be ! StringToBigInt(py).
      2. ii. If ny is NaN, return undefined.
      3. iii. Return BigInt::lessThan(px, ny).
    2. b. If Type(px) is String and Type(py) is BigInt, then
      1. i. Let nx be ! StringToBigInt(px).
      2. ii. If nx is NaN, return undefined.
      3. iii. Return BigInt::lessThan(nx, py).
    3. c. NOTE: Because px and py are primitive values, evaluation order is not important.
    4. d. Let nx be ? ToNumeric(px).
    5. e. Let ny be ? ToNumeric(py).
    6. f. If Type(nx) is the same as Type(ny), return Type(nx)::lessThan(nx, ny).
    7. g. Assert: Type(nx) is BigInt and Type(ny) is Number, or Type(nx) is Number and Type(ny) is BigInt.
    8. h. If nx or ny is NaN, return undefined.
    9. i. If nx is -∞𝔽 or ny is +∞𝔽, return true.
    10. j. If nx is +∞𝔽 or ny is -∞𝔽, return false.
    11. k. If (nx) < (ny), return true; otherwise return false.
Note 1

Step [3](https://tc39.es/ecma262/#step-arc-string-check) differs from step [2.c](https://tc39.es/ecma262/#step-binary-op-string-check) in the algorithm that handles the addition operator `+` ([13.15.3](https://tc39.es/ecma262/#sec-applystringornumericbinaryoperator)) by using the logical-and operation instead of the logical-or operation.
Enter fullscreen mode Exit fullscreen mode
Note 2

The comparison of Strings uses a simple lexicographic ordering on sequences of code unit values. There is no attempt to use the more complex, semantically oriented definitions of character or string equality and collating order defined in the Unicode specification. Therefore String values that are canonically equal according to the Unicode standard could test as unequal. In effect this algorithm assumes that both Strings are already in normalized form. Also, note that for strings containing supplementary characters, lexicographic ordering on sequences of UTF-16 code unit values differs from that on sequences of code point values.
Enter fullscreen mode Exit fullscreen mode

7.2.14 IsLooselyEqual ( x, y )


The abstract operation IsLooselyEqual takes arguments x (an ECMAScript language value) and y (an ECMAScript language value). It provides the semantics for the comparison x == y, returning true or false. It performs the following steps when called:

  1. 1. If Type(x) is the same as Type(y), then
    1. a. Return IsStrictlyEqual(x, y).
  2. 2. If x is null and y is undefined, return true.
  3. 3. If x is undefined and y is null, return true.
  4. 4. NOTE: This step is replaced in section B.3.6.2.
  5. 5. If Type(x) is Number and Type(y) is String, return IsLooselyEqual(x, ! ToNumber(y)).
  6. 6. If Type(x) is String and Type(y) is Number, return IsLooselyEqual(! ToNumber(x), y).
  7. 7. If Type(x) is BigInt and Type(y) is String, then
    1. a. Let n be ! StringToBigInt(y).
    2. b. If n is NaN, return false.
    3. c. Return IsLooselyEqual(x, n).
  8. 8. If Type(x) is String and Type(y) is BigInt, return IsLooselyEqual(y, x).
  9. 9. If Type(x) is Boolean, return IsLooselyEqual(! ToNumber(x), y).
  10. 10. If Type(y) is Boolean, return IsLooselyEqual(x, ! ToNumber(y)).
  11. 11. If Type(x) is either String, Number, BigInt, or Symbol and Type(y) is Object, return IsLooselyEqual(x, ? ToPrimitive(y)).
  12. 12. If Type(x) is Object and Type(y) is either String, Number, BigInt, or Symbol, return IsLooselyEqual(? ToPrimitive(x), y).
  13. 13. If Type(x) is BigInt and Type(y) is Number, or if Type(x) is Number and Type(y) is BigInt, then
    1. a. If x or y are any of NaN, +∞𝔽, or -∞𝔽, return false.
    2. b. If (x) = (y), return true; otherwise return false.
  14. 14. Return false.

7.2.15 IsStrictlyEqual ( x, y )


The abstract operation IsStrictlyEqual takes arguments x (an ECMAScript language value) and y (an ECMAScript language value). It provides the semantics for the comparison x === y, returning true or false. It performs the following steps when called:

  1. 1. If Type(x) is different from Type(y), return false.
  2. 2. If Type(x) is Number or BigInt, then
    1. a. Return ! Type(x)::equal(x, y).
  3. 3. Return ! SameValueNonNumeric(x, y).

Note

This algorithm differs from the SameValue Algorithm in its treatment of signed zeroes and NaNs.

Top comments (0)