Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs

Dashboard
Notifications
Mark all as read
Q&A

What's the difference between =, == and === operators in JavaScript?

+5
−0

While learning JavaScript, I started to see =, == and === operators. What's the difference between them?

Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

3 answers

+7
−0

Assignment =

= is the assignment operator. There's nothing much to say here.

Abstract Equality ==

== is abstract equality - it will attempt to perform a type conversion before evaluating equality.

E.g.

1 == '1'
1 == true
null == undefined

Objects only compare equal if both sides reference the same object.

Therefore, perhaps counterintuitively,

var x = {};
console.log(x == {}) // False

Strict Equality ===

=== is strict equality - it checks that both have the same type and have the same value. The example above would not compare equal if it were using the strict equality operator.

Note that NaN doesn't compare equal to anything, including NaN

NaN != NaN
NaN !== NaN

Bonus: Object.is

Object.is is even stricter than ===, requiring exact values.

Object.is(+0, -0) // false

It is useful for NaN though, as Object.is(NaN, NaN) returns true.

Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

+4
−0

Assignment (=)

= is the assignment operator: it assigns a value to "something".

One important detail is that an assignment expression not only assigns a value, but it also returns it. This allows chaining, such as:

x = y = z = 1; // all variables will be assigned the value 1

According to the operator precedence rules, assignment is right-associative, so the code above is actually equivalent to:

x = (y = (z = 1));

As the expression also returns the assigned value, the code above is evaluated as:

  • z is assigned the value 1
  • the expression z = 1 returns the value 1
  • y is assigned the value returned by (z = 1) (which is also 1)
  • the expression (y = (z = 1)) returns the value 1
  • x is assigned the value returned by (y = (z = 1)) (which is also 1)

This allows even more complicated things, such as:

x = (y = (z = 1) + 1) + y;

In this case, the code executes as follows:

  • z is assigned the value 1
  • the expression z = 1 returns the value 1
  • y is assigned the value returned by (z = 1) + 1 (which is 2)
  • the expression (y = (z = 1) + 1) returns the value 2
  • x is assigned the value returned by (y = (z = 1) + 1) + y (which is 4)

Although I'd never use expressions like this in production code. But the fact that an assignment returns a value can be useful in cases like this:

while ((x = somefunc()) >= 0) {
    // do something with x
}

Assuming that somefunc returns some number, and I want to loop until this number is negative (and also do something with it inside the loop). Of course I could rewrite the same code as:

while (true) {
    x = somefunc();
    if (x < 0)
        break;
    // do something with x
}

But I think the former is more straighforward.


Another caveat regards to variable declaration. See this code:

const x = y = 1;
y = 2; // ok
x = 2; // ERROR

A const variable can't be changed through assignment, so trying to assign x = 2 causes an error. But y = 2 is perfectly fine, because const applies only to x. Remember that = is right-associative, so the first line above corresponds to:

const x = (y = 1);

If I want both x and y to be constants, I'd have to do this:

const x = 1, y = 1;

And last but not least, the left side of = is not restricted to single variable names:

// if x is an array, assign value to specific index
x[2] = value;

// assign value to a property of "x" object
x.property = value;

// if value is an array, x and y will be its first and second elements
[x, y] = value;

// destructuring assignment, get "name" and "age" properties of object and assigning them to the respective variables
var { name, age } = obj;

Equality Operators: == vs ===

According to MDN, == is the equality operator and === is the strict equality operator, but the ECMAScript language specification just calls them "Equality Operators". You can call them "loose" and "strict" equality, though, as these terms usage has become common and well known.

Both always return a boolean value (either true or false). The only difference, according to the evaluation rules, is the algorithm used to determine equality.

== or "loose equality"

The == operator uses the IsLooselyEqual operation, which makes some type coercions when the operands are of different types. The rules are somewhat complicated (if you compare a number and a string, the string will be converted to a number using the rules defined in the spec, but comparing a number and an object will make the object to be converted to a primitive, etc).

This can cause some strange and unexpected behaviour in many cases, such as 0 == [], "1" == [1] and "" == [[[]]], all of them resulting in true.

Although chaining this operator produces valid code (aka "it runs without compile-errors"), it doesn't work the way you'd expect. Example:

x = y = z = 0; // assign zero to all variables
console.log(x == y == z); // false

According to this table, both == and === are evaluated left-to-right, which means that the expression x == y == z is equivalent to:

(x == y) == z

Hence, x == y evaluates to true (as both x and y are zero), and then true == z evaluates to false. To test if the three variables are equal, you should do x == y && y == z (or x === y && y === z).

But all these type coercion mess applies only when the two operands are of different types. When they are of the same type, both == and === behave the same way. In the specification of IsLooselyEqual operation, the first step is:

  1. If Type(x) is the same as Type(y), then
    • Return IsStrictlyEqual(x, y).

And according to the spec, the IsStrictlyEqual operation is the same one used by the === operator.

=== or "strict equality"

As mentioned above, the === operator uses the IsStrictlyEqual operation, which in turn does the following:

  • if the operands are of type Number or BigInt, it calls the respective equal operation (this one for Number or this one for BigInt).
  • in any other case, it uses the SameValueNonNumeric operation, which defines specific rules for each type

The difference from == is that === doesn't do any type coercion: if the operands are of different types, it returns false (that's the first thing it checks, BTW).

But there's one caveat: the "same type" definition is a little bit tricky when objects are involved. Ex:

x = [1, 2];
y = [1, 2];
z = x;
console.log(typeof x, typeof y, typeof z); // "object" "object" "object"
console.log(x === y); // false (although they have the same type)
console.log(x === z); // true (they reference the same object)

The assignment to y actually creates another array (hence, it's a different object, although it has the same values of x). And when the operands type is neither Number, BigInt, Undefined, Null, String, Boolean nor Symbol, the SameValueNonNumeric operation only returns true if both operands are the same object.


The differences between == and ===, and their somewhat complicated rules, might lead to lots of corner cases, such as null == undefined being true while null === undefined is false, and many more (some already mentioned in the other answers).

Here you can find some interesting tables with lots of those cases. I'm reproducing some below.

For the == operator:

loose equality

And for the === operator:

strict equality

Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

+2
−0

1. =

= is an assignment operator in JavaScript, it is used to assign a value to a variable. e.g:

const test = 1;

console.log(test);
// expected output: 1.

In the above example, we have assigned the value 1 to the variable test using the assignment operator =.

Here is an another examples from MDN:

const x = 2;
const y = 3;

console.log(x);
// expected output: 2.

console.log(x = y + 1); // 3 + 1
// expected output: 4.

console.log(x = x * y); // 4 * 3
// expected output: 12.

Learn more about = at MDN.

2. ==

== is a comparison operator in JavaScript, it attempts to convert and compare operands that are of different types, returning a boolean result (true Or false). e.g:

console.log(1 == 1);
// expected output: true.

In the above example, we compared 1, which is a number, to other 1, which is also a number, that mean the expected output will be true since they are the same type, we done this using the comparison operator ==.

Here is an another examples from MDN:

console.log('hello' == 'hello');
// expected output: true.

console.log(1 == "1");
// expected output: true.

console.log(0 == false);
// expected output: true.

Learn more about == at MDN.

3. ===

=== is a strict equality comparison operator in JavaScript, it always considers operands of different types to be different, returning a boolean result (true Or false). e.g:

console.log(true === "true");
// expected output: false.

Since === considers operands of different types to be different, so true is considered 1 and "true" is considered NaN, so the expected output will be false since they different types, we done this using the strict equality comparison operator ===.

Here is an another examples from MDN:

console.log(1 === 1);
// expected output: true.

console.log('hello' === 'hello');
// expected output: true.

console.log('1' ===  1);
// expected output: false.

console.log(0 === false);
// expected output: false.

Learn more about === at MDN.

Summarize

  1. = is an assignment operator.
  2. == is a comparison operator.
  3. === is a strict equality comparison operator.
Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

Sign up to answer this question »