Home > Software engineering >  Does the `===` operator in Javascript have separate definitions for primitives vs non-primitives?
Does the `===` operator in Javascript have separate definitions for primitives vs non-primitives?

Time:12-05

With the === operator in Javascript, if it operators on primitives, it returns false if either the values are different or the types are different. If it's operating on non-primitives, it returns false if the two operands don't point to the same object.

This seems like the === has separate definitions when applied to primitives and non-primitives. Like "if operands are primitives, do this, else do this". Is there a broader definition of === that encompasses its treatment of both primitives and non-primitives? Like "whether primitives or non-primitive, do this"?

CodePudding user response:

Yes, to some extent - there's a bit of a process here.

7.2.15 IsStrictlyEqual ( x, y )

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

and

7.2.12 SameValueNonNumber ( x, y )

  1. Assert: Type(x) is the same as Type(y).
  2. If x is a BigInt, then a. Return BigInt::equal(x, y).
  3. If x is undefined, return true.
  4. If x is null, return true.
  5. If x is a String, then 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. If x is a Boolean, then a. If x and y are both true or both false, return true; otherwise, return false.
  7. If x is a Symbol, then a. If x and y are both the same Symbol value, return true; otherwise, return false.
  8. If x and y are the same Object value, return true. Otherwise, return false.

CodePudding user response:

The === operator in JavaScript, also known as the strict equality operator, is defined to check for strict equality between its operands. This means that it checks both the value and the type of the operands, and returns true only if they are equal in both value and type.

The strict equality operator has the same behavior regardless of whether it is operating on primitives or non-primitives. It will return true only if the operands have the same value and type.

For example, the following expressions will all return true when using the strict equality operator:

1 === 1 // true (same value and type)
"hello" === "hello" // true (same value and type)
true === true // true (same value and type)
undefined === undefined // true (same value and type)
null === null // true (same value and type)

And the following expressions will all return false when using the strict equality operator:

1 === 2 // false (different value)
1 === "1" // false (different type)
"hello" === "world" // false (different value)
true === false // false (different value)
undefined === null // false (different type)

When the strict equality operator is applied to non-primitives, such as objects or arrays, it checks whether the operands refer to the same object in memory. This means that it will return true only if the operands are the same object, and not just if they have the same properties or values.

For example, the following expression will return true when using the strict equality operator:

const obj = { a: 1, b: 2 };
obj === obj // true (same object)

But the following expression will return false when using the strict equality operator:

const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };
obj1 === obj2 // false (different objects)

In summary, the strict equality operator checks for strict equality between its operands, regardless of whether they are primitives or non-primitives. It returns true only if the operands have the same value and type, or if they refer to the same object in memory.

CodePudding user response:

The only real answer here is the spec, where we see === defined:

EqualityExpression : EqualityExpression === RelationalExpression

 1. Let lref be ? Evaluation of EqualityExpression.
 2. Let lval be ? GetValue(lref).
 3. Let rref be ? Evaluation of RelationalExpression.
 4. Let rval be ? GetValue(rref).
 5. Return IsStrictlyEqual(rval, lval).

So we're comparing "whatever the GetValue spec function says we should be comparing", paired with "and we have to use the strict equality test for that", so we're not so much comparing "two primitive values, or two references". There's a few more steps involved, which have zero relevance to "actually using JS" in most circumstances, so for practical purposes they simply don't matter...but when you have fundamental questions, the spec is the fundaments =)

  • Related