Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
What's the difference between =, == and === operators in JavaScript?
While learning JavaScript, I started to see =
, ==
and ===
operators. What's the difference between them?
3 answers
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
-
=
is an assignment operator. -
==
is a comparison operator. -
===
is a strict equality comparison operator.
0 comment threads
The following users marked this post as Works for me:
User | Comment | Date |
---|---|---|
Kevin M. Mansour | (no comment) | Oct 4, 2021 at 17:03 |
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.
0 comment threads
The following users marked this post as Works for me:
User | Comment | Date |
---|---|---|
Kevin M. Mansour | (no comment) | Oct 4, 2021 at 17:03 |
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 value1
- the expression
z = 1
returns the value1
-
y
is assigned the value returned by(z = 1)
(which is also1
) - the expression
(y = (z = 1))
returns the value1
-
x
is assigned the value returned by(y = (z = 1))
(which is also1
)
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 value1
- the expression
z = 1
returns the value1
-
y
is assigned the value returned by(z = 1) + 1
(which is2
) - the expression
(y = (z = 1) + 1)
returns the value2
-
x
is assigned the value returned by(y = (z = 1) + 1) + y
(which is4
)
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:
- If
Type(x)
is the same asType(y)
, then- Return
IsStrictlyEqual(x, y)
.
- Return
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
orBigInt
, it calls the respectiveequal
operation (this one forNumber
or this one forBigInt
). - 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:
And for the ===
operator:
0 comment threads