So sánh even then until additional năm 2024

Note that the distinction between these all have to do with their handling of primitives; none of them compares whether the parameters are conceptually similar in structure. For any non-primitive objects

const num = 0;
const big = 0n;
const str = "0";
const obj = new String("0");
console.log(num == str); // true
console.log(big == num); // true
console.log(str == big); // true
console.log(num == obj); // true
console.log(big == obj); // true
console.log(str == obj); // true

Show

    9 and

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    0 which have the same structure but are distinct objects themselves, all of the above forms will evaluate to

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    0.

    Strict equality compares two values for equality. Neither value is implicitly converted to some other value before being compared. If the values have different types, the values are considered unequal. If the values have the same type, are not numbers, and have the same value, they're considered equal. Finally, if both values are numbers, they're considered equal if they're both not

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1 and are the same value, or if one is

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    3 and one is

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2.

    const num = 0;
    const obj = new String("0");
    const str = "0";
    console.log(num === num); // true
    console.log(obj === obj); // true
    console.log(str === str); // true
    console.log(num === obj); // false
    console.log(num === str); // false
    console.log(obj === str); // false
    console.log(null === undefined); // false
    console.log(obj === null); // false
    console.log(obj === undefined); // false
    

    Strict equality is almost always the correct comparison operation to use. For all values except numbers, it uses the obvious semantics: a value is only equal to itself. For numbers it uses slightly different semantics to gloss over two different edge cases. The first is that floating point zero is either positively or negatively signed. This is useful in representing certain mathematical solutions, but as most situations don't care about the difference between

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    3 and

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2, strict equality treats them as the same value. The second is that floating point includes the concept of a not-a-number value,

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1, to represent the solution to certain ill-defined mathematical problems: negative infinity added to positive infinity, for example. Strict equality treats

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1 as unequal to every other value — including itself. (The only case in which

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    9 is

    function sameValueZero(x, y) {
      if (typeof x === "number" && typeof y === "number") {
        // x and y are equal (may be -0 and 0) or they are both NaN
        return x === y || (x !== x && y !== y);
      }
      return x === y;
    }
    

    0 is when

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    9 is

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1.)

    Besides ===, strict equality is also used by array index-finding methods including

    function sameValueZero(x, y) {
      if (typeof x === "number" && typeof y === "number") {
        // x and y are equal (may be -0 and 0) or they are both NaN
        return x === y || (x !== x && y !== y);
      }
      return x === y;
    }
    

    4,

    function sameValueZero(x, y) {
      if (typeof x === "number" && typeof y === "number") {
        // x and y are equal (may be -0 and 0) or they are both NaN
        return x === y || (x !== x && y !== y);
      }
      return x === y;
    }
    

    5,

    function sameValueZero(x, y) {
      if (typeof x === "number" && typeof y === "number") {
        // x and y are equal (may be -0 and 0) or they are both NaN
        return x === y || (x !== x && y !== y);
      }
      return x === y;
    }
    

    6,

    function sameValueZero(x, y) {
      if (typeof x === "number" && typeof y === "number") {
        // x and y are equal (may be -0 and 0) or they are both NaN
        return x === y || (x !== x && y !== y);
      }
      return x === y;
    }
    

    7, and

    function sameValueZero(x, y) {
      if (typeof x === "number" && typeof y === "number") {
        // x and y are equal (may be -0 and 0) or they are both NaN
        return x === y || (x !== x && y !== y);
      }
      return x === y;
    }
    

    8-matching. This means you cannot use

    function sameValueZero(x, y) {
      if (typeof x === "number" && typeof y === "number") {
        // x and y are equal (may be -0 and 0) or they are both NaN
        return x === y || (x !== x && y !== y);
      }
      return x === y;
    }
    

    9 to find the index of a

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1 value in an array, or use

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1 as a

    function sameValueZero(x, y) {
      if (typeof x === "number" && typeof y === "number") {
        // x and y are equal (may be -0 and 0) or they are both NaN
        return x === y || (x !== x && y !== y);
      }
      return x === y;
    }
    

    8 value in a

    const stoppingForce = obj.mass * -obj.velocity;
    

    3 statement and make it match anything.

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    Loose equality is symmetric:

    const stoppingForce = obj.mass * -obj.velocity;
    

    4 always has identical semantics to

    const stoppingForce = obj.mass * -obj.velocity;
    

    5 for any values of

    const stoppingForce = obj.mass * -obj.velocity;
    

    6 and

    const stoppingForce = obj.mass * -obj.velocity;
    

    7 (except for the order of applied conversions). The behavior for performing loose equality using == is as follows:

    1. If the operands have the same type, they are compared as follows:
      • Object: return

        function sameValueZero(x, y) {

         if (typeof x === "number" && typeof y === "number") {  
           // x and y are equal (may be -0 and 0) or they are both NaN  
           return x === y || (x !== x && y !== y);  
         }  
         return x === y;  
        
        }

        0 only if both operands reference the same object.
      • String: return

        function sameValueZero(x, y) {

         if (typeof x === "number" && typeof y === "number") {  
           // x and y are equal (may be -0 and 0) or they are both NaN  
           return x === y || (x !== x && y !== y);  
         }  
         return x === y;  
        
        }

        0 only if both operands have the same characters in the same order.
      • Number: return

        function sameValueZero(x, y) {

         if (typeof x === "number" && typeof y === "number") {  
           // x and y are equal (may be -0 and 0) or they are both NaN  
           return x === y || (x !== x && y !== y);  
         }  
         return x === y;  
        
        }

        0 only if both operands have the same value.

        console.log([NaN].indexOf(NaN)); // -1 switch (NaN) {

         case NaN:  
           console.log("Surprise"); // Nothing is logged  
        
        }

        3 and

        console.log([NaN].indexOf(NaN)); // -1 switch (NaN) {

         case NaN:  
           console.log("Surprise"); // Nothing is logged  
        
        }

        2 are treated as the same value. If either operand is

        console.log([NaN].indexOf(NaN)); // -1 switch (NaN) {

         case NaN:  
           console.log("Surprise"); // Nothing is logged  
        
        }

        1, return

        const num = 0; const big = 0n; const str = "0"; const obj = new String("0"); console.log(num == str); // true console.log(big == num); // true console.log(str == big); // true console.log(num == obj); // true console.log(big == obj); // true console.log(str == obj); // true

        0; so

        console.log([NaN].indexOf(NaN)); // -1 switch (NaN) {

         case NaN:  
           console.log("Surprise"); // Nothing is logged  
        
        }

        1 is never equal to

        console.log([NaN].indexOf(NaN)); // -1 switch (NaN) {

         case NaN:  
           console.log("Surprise"); // Nothing is logged  
        
        }

      • Boolean: return

        function sameValueZero(x, y) {

         if (typeof x === "number" && typeof y === "number") {  
           // x and y are equal (may be -0 and 0) or they are both NaN  
           return x === y || (x !== x && y !== y);  
         }  
         return x === y;  
        
        }

        0 only if operands are both

        function sameValueZero(x, y) {

         if (typeof x === "number" && typeof y === "number") {  
           // x and y are equal (may be -0 and 0) or they are both NaN  
           return x === y || (x !== x && y !== y);  
         }  
         return x === y;  
        
        }

        0 or both

        const num = 0; const big = 0n; const str = "0"; const obj = new String("0"); console.log(num == str); // true console.log(big == num); // true console.log(str == big); // true console.log(num == obj); // true console.log(big == obj); // true console.log(str == obj); // true

      • BigInt: return

        function sameValueZero(x, y) {

         if (typeof x === "number" && typeof y === "number") {  
           // x and y are equal (may be -0 and 0) or they are both NaN  
           return x === y || (x !== x && y !== y);  
         }  
         return x === y;  
        
        }

        0 only if both operands have the same value.
      • Symbol: return

        function sameValueZero(x, y) {

         if (typeof x === "number" && typeof y === "number") {  
           // x and y are equal (may be -0 and 0) or they are both NaN  
           return x === y || (x !== x && y !== y);  
         }  
         return x === y;  
        
        }

        0 only if both operands reference the same symbol.
    2. If one of the operands is ===`3 or ===4, the other must also be ===3 or ===4 to return

      function sameValueZero(x, y) { if (typeof x === "number" && typeof y === "number") {

      // x and y are equal (may be -0 and 0) or they are both NaN  
      return x === y || (x !== x && y !== y);  
      
      } return x === y; }

      0. Otherwise return

      const num = 0; const big = 0n; const str = "0"; const obj = new String("0"); console.log(num == str); // true console.log(big == num); // true console.log(str == big); // true console.log(num == obj); // true console.log(big == obj); // true console.log(str == obj); // true

      ` 0.
    3. If one of the operands is an object and the other is a primitive, .
    4. At this step, both operands are converted to primitives (one of String, Number, Boolean, Symbol, and BigInt). The rest of the conversion is done case-by-case.
      • If they are of the same type, compare them using step 1.
      • If one of the operands is a Symbol but the other is not, return

        const num = 0; const big = 0n; const str = "0"; const obj = new String("0"); console.log(num == str); // true console.log(big == num); // true console.log(str == big); // true console.log(num == obj); // true console.log(big == obj); // true console.log(str == obj); // true

      • If one of the operands is a Boolean but the other is not, :

        function sameValueZero(x, y) {

         if (typeof x === "number" && typeof y === "number") {  
           // x and y are equal (may be -0 and 0) or they are both NaN  
           return x === y || (x !== x && y !== y);  
         }  
         return x === y;  
        
        }

        0 is converted to 1, and

        const num = 0; const big = 0n; const str = "0"; const obj = new String("0"); console.log(num == str); // true console.log(big == num); // true console.log(str == big); // true console.log(num == obj); // true console.log(big == obj); // true console.log(str == obj); // true

        0 is converted to 0. Then compare the two operands loosely again.
      • Number to String: . Conversion failure results in

        console.log([NaN].indexOf(NaN)); // -1 switch (NaN) {

         case NaN:  
           console.log("Surprise"); // Nothing is logged  
        
        }

        1, which will guarantee the equality to be

        const num = 0; const big = 0n; const str = "0"; const obj = new String("0"); console.log(num == str); // true console.log(big == num); // true console.log(str == big); // true console.log(num == obj); // true console.log(big == obj); // true console.log(str == obj); // true

      • Number to BigInt: compare by their numeric value. If the number is ±Infinity or

        console.log([NaN].indexOf(NaN)); // -1 switch (NaN) {

         case NaN:  
           console.log("Surprise"); // Nothing is logged  
        
        }

        1, return

        const num = 0; const big = 0n; const str = "0"; const obj = new String("0"); console.log(num == str); // true console.log(big == num); // true console.log(str == big); // true console.log(num == obj); // true console.log(big == obj); // true console.log(str == obj); // true

      • String to BigInt: convert the string to a BigInt using the same algorithm as the ==6 constructor. If conversion fails, return `

        const num = 0; const big = 0n; const str = "0"; const obj = new String("0"); console.log(num == str); // true console.log(big == num); // true console.log(str == big); // true console.log(num == obj); // true console.log(big == obj); // true console.log(str == obj); // true

        ` 0.

    Traditionally, and according to ECMAScript, all primitives and objects are loosely unequal to ===`4 and ===3. But most browsers permit a very narrow class of objects (specifically, the `Object.is()`0 object for any page), in some contexts, to act as if they emulate the value ===4. Loose equality is one such context: `Object.is()`2 and `Object.is()`3 evaluate to true if, and only if, A is an object that emulates ===4. In all other cases an object is never loosely equal to ===4 or ===`3.

    In most cases, using loose equality is discouraged. The result of a comparison using strict equality is easier to predict, and may evaluate more quickly due to the lack of type coercion.

    The following example demonstrates loose equality comparisons involving the number primitive `Object.is()`7, the bigint primitive `Object.is()`8, the string primitive `Object.is()`9, and an object whose

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    00 value is `Object.is()`9.

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    Loose equality is only used by the == operator.

    Same-value equality determines whether two values are functionally identical in all contexts. (This use case demonstrates an instance of the Liskov substitution principle.) One instance occurs when an attempt is made to mutate an immutable property:

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    
    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    03 will throw an exception when attempting to change an immutable property, but it does nothing if no actual change is requested. If

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    04 is

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2, no change has been requested, and no error will be thrown. Internally, when an immutable property is redefined, the newly-specified value is compared against the current value using same-value equality.

    Same-value equality is provided by the

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    06 method. It's used almost everywhere in the language where a value of equivalent identity is expected.

    Similar to same-value equality, but +0 and -0 are considered equal.

    Same-value-zero equality is not exposed as a JavaScript API, but can be implemented with custom code:

    function sameValueZero(x, y) {
      if (typeof x === "number" && typeof y === "number") {
        // x and y are equal (may be -0 and 0) or they are both NaN
        return x === y || (x !== x && y !== y);
      }
      return x === y;
    }
    

    Same-value-zero only differs from strict equality by treating

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1 as equivalent, and only differs from same-value equality by treating

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2 as equivalent to `Object.is()`7. This makes it usually have the most sensible behavior during searching, especially when working with

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1. It's used by

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    11,

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    12, as well as

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    13 and

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    14 methods for comparing key equality.

    People often compare double equals and triple equals by saying one is an "enhanced" version of the other. For example, double equals could be said as an extended version of triple equals, because the former does everything that the latter does, but with type conversion on its operands — for example,

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    15. Alternatively, it can be claimed that double equals is the baseline, and triple equals is an enhanced version, because it requires the two operands to be the same type, so it adds an extra constraint.

    However, this way of thinking implies that the equality comparisons form a one-dimensional "spectrum" where "totally strict" lies on one end and "totally loose" lies on the other. This model falls short with

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    06, because it isn't "looser" than double equals or "stricter" than triple equals, nor does it fit somewhere in between (i.e., being both stricter than double equals, but looser than triple equals). We can see from the sameness comparisons table below that this is due to the way that

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    06 handles

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1. Notice that if

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    19 evaluated to

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    0, we could say that it fits on the loose/strict spectrum as an even stricter form of triple equals, one that distinguishes between

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2 and

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    3. The

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1 handling means this is untrue, however. Unfortunately,

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    06 has to be thought of in terms of its specific characteristics, rather than its looseness or strictness with regard to the equality operators.

    x y`== ===`

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    06

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    28`===4===`4

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31`===3===`3

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    function sameValueZero(x, y) {
      if (typeof x === "number" && typeof y === "number") {
        // x and y are equal (may be -0 and 0) or they are both NaN
        return x === y || (x !== x && y !== y);
      }
      return x === y;
    }
    

    0

    function sameValueZero(x, y) {
      if (typeof x === "number" && typeof y === "number") {
        // x and y are equal (may be -0 and 0) or they are both NaN
        return x === y || (x !== x && y !== y);
      }
      return x === y;
    }
    

    0

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    0

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    0

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    53

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    53

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31`Object.is()`7`Object.is()`7

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    3

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    3`Object.is()`7

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2`Object.is()`7

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31`Object.is()`8

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    84

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31`Object.is()`7

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    0

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    95

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    0

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    95`Object.is()`7

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69`Object.is()`9`Object.is()`7

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    13

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    14

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    19

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    20

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    25

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    53

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69`===3===`4

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69`===`3

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    0

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69`===`4

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    0

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    49

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    49

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    25

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    25

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69`Object.is()7===`3

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69`Object.is()`7

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    53

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    69

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    31

    In general, the only time

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    06's special behavior towards zeros is likely to be of interest is in the pursuit of certain meta-programming schemes, especially regarding property descriptors, when it is desirable for your work to mirror some of the characteristics of

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    03. If your use case does not require this, it is suggested to avoid

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    06 and use === instead. Even if your requirements involve having comparisons between two

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1 values evaluate to

    function sameValueZero(x, y) {
      if (typeof x === "number" && typeof y === "number") {
        // x and y are equal (may be -0 and 0) or they are both NaN
        return x === y || (x !== x && y !== y);
      }
      return x === y;
    }
    

    0, generally it is easier to special-case the

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1 checks (using the

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    92 method available from previous versions of ECMAScript) than it is to work out how surrounding computations might affect the sign of any zeros you encounter in your comparison.

    Here's a non-exhaustive list of built-in methods and operators that might cause a distinction between

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2 and

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    3 to manifest itself in your code:

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    95 (unary negation)

    Consider the following example:

    const stoppingForce = obj.mass * -obj.velocity;
    

    If

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    96 is `Object.is()`7 (or computes to `Object.is()`7), a

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2 is introduced at that place and propagates out into

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    00.

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    01,

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    02,

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    03,

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    04

    In some cases, it's possible for a

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2 to be introduced into an expression as a return value of these methods even when no

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2 exists as one of the parameters. For example, using

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    03 to raise

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    08 to the power of any negative, odd exponent evaluates to

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2. Refer to the documentation for the individual methods.

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    10,

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    11,

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    12,

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    13,

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    14,

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    15

    It's possible to get a

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2 return value out of these methods in some cases where a

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2 exists as one of the parameters. E.g.,

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    18 evaluates to

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2. Refer to the documentation for the individual methods.

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    20,

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    21,

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    22

    Each of these operators uses the ToInt32 algorithm internally. Since there is only one representation for 0 in the internal 32-bit integer type,

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2 will not survive a round trip after an inverse operation. E.g., both

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    24 and

    // Add an immutable NEGATIVE_ZERO property to the Number constructor.
    Object.defineProperty(Number, "NEGATIVE_ZERO", {
      value: -0,
      writable: false,
      configurable: false,
      enumerable: false,
    });
    function attemptMutation(v) {
      Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
    }
    

    25 evaluate to

    const num = 0;
    const big = 0n;
    const str = "0";
    const obj = new String("0");
    console.log(num == str); // true
    console.log(big == num); // true
    console.log(str == big); // true
    console.log(num == obj); // true
    console.log(big == obj); // true
    console.log(str == obj); // true
    

    0.

    Relying on

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    06 when the signedness of zeros is not taken into account can be hazardous. Of course, when the intent is to distinguish between

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    2 and

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    3, it does exactly what's desired.

    The

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    06 specification treats all instances of

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1 as the same object. However, since typed arrays are available, we can have distinct floating point representations of

    console.log([NaN].indexOf(NaN)); // -1
    switch (NaN) {
      case NaN:
        console.log("Surprise"); // Nothing is logged
    }
    

    1 which don't behave identically in all contexts. For example: