乐闻世界logo
搜索文章和话题

Which equals operator vs should be used in javascript comparisons

5个答案

1
2
3
4
5

In the world of JavaScript, comparison operators are indispensable in our daily coding. They help us understand and determine whether the values of different variables or expressions are equal. When discussing equality comparisons, there are two operators that are very similar but fundamentally different: == (equality operator) and === (strict equality operator). Understanding their differences is crucial for writing reliable and efficient code.

== Equality Operator: Type Coercion in Action

The == operator in JavaScript is known as 'loose equality' or 'non-strict equality'. When using == to compare two values, if they are not of the same type, JavaScript performs type coercion to convert them into the same type before comparison. This type conversion is commonly referred to as 'type coercion'.

Example: 🌰

javascript
0 == '0'; // true, because the string '0' is coerced to the number 0 '1' == 1; // true, same as above null == undefined; // true, null and undefined are considered equal in loose equality

This behavior of the == operator can lead to unexpected results, sometimes causing hard-to-find bugs. Therefore, it is often considered a less reliable comparison method in JavaScript.

=== Strict Equality Operator: Strict Equality in Action

Differing from the == operator, the === operator does not perform type coercion during comparison. If the types of two values are different, they are considered unequal. Therefore, === is known as the 'strict equality' operator.

Another Example: 🌰

javascript
0 === '0'; // false, because their types differ: one is a number, the other is a string '1' === 1; // false, same as above null === undefined; // false, null and undefined have different types

Using the === operator can make your code logic clearer, more predictable, and reduce the risk of hidden bugs.

So, which one should we choose?

In most cases, it is recommended to use the === strict equality operator, as it provides type-safe comparison and reduces many unnecessary issues. Only consider using == when you explicitly need type conversion.

Best Practices

Suppose you are handling a web form where the user input is a string of numbers, and you need to compare it with a numeric value.

javascript
const userInput = '123'; const targetValue = 123; // Using == because we know the values should be equal even if types differ if (userInput == targetValue) { console.log('User input matches!'); }

In this case, you might choose to use == as it simplifies the code. However, for better code quality and maintainability, you should consider explicitly converting the type and then using === for comparison.

javascript
const userInput = '123'; const targetValue = 123; // Explicitly convert the type and then use === for comparison if (Number(userInput) === targetValue) { console.log('User input matches!'); }
2024年6月29日 12:07 回复

In JavaScript, it is generally recommended to use the === (strict equality) operator for comparisons rather than the == (loose equality) operator.

The === (strict equality) operator compares both the type and value of two values, and it returns true only when both are equal. This means that if the types of the two values differ, they are never considered strictly equal.

javascript
3 === '3' // false, because one is a number and the other is a string

The == (loose equality) operator performs type coercion (if the types differ) before comparing the values.

javascript
3 == '3' // true, because the string '3' is implicitly converted to the number 3

Using === helps prevent potential errors and confusion caused by JavaScript's automatic type coercion, making it the preferred choice. However, in rare cases where explicit type conversion is required, using == may be appropriate. But in most cases, it is recommended to use === to ensure the accuracy and clarity of your code.

2024年6月29日 12:07 回复

In JavaScript, null and undefined both represent the absence of a value, specifically:

javascript
var a; // a is declared without assignment, resulting in undefined var b = null; // b is assigned null, indicating an empty value

Here, both variables a and b lack specific values.

Conversely, while 0, false, and the empty string '' represent their respective values, they share a common characteristic: they are all falsy values, meaning they evaluate to false in conditional statements.

Accordingly, 0, false, and '' constitute a set of special falsy values. In contrast, null and undefined represent another set of special 'no-value' states.

As illustrated in the comparison diagram below, null and undefined are considered equal in JavaScript. Likewise, 0, false, and '' are considered equal to each other. However, all of them are still classified as falsy values.

Image description placeholder

Conversely, any object (e.g., {} and arrays), non-empty strings, and the boolean true are considered truthy values, meaning they evaluate to true in conditional statements. However, these truthy values do not imply they are equal to each other.

2024年6月29日 12:07 回复

Why is == so unpredictable?

What happens when you compare an empty string "" with the number zero 0?

true

Correct, according to the rules of ==, an empty string and the number zero are considered equal.

But that's not all. Let's look at this example:

shell
'0' == false // true

Arrays can be even stranger.

shell
[1] == true // true [] == false // true [[]] == false // true [0] == false // true

Strings can be even weirder.

shell
[1,2,3] == '1,2,3' // true - Is that really true?! '\r\n\t' == 0 // true - That's absurd!

Things get worse:

When does equality not equal equality?

shell
let A = '' // empty string let B = 0 // number zero let C = '0' // string zero A == B // true - Okay... B == C // true - So far so good... A == C // **FALSE** - Plot twist!

Let's review:

shell
(A == B) && (B == C) // true (A == C) // **FALSE**

These weird things only happen with primitive types.

When you use == to compare objects, things become completely different.

At this point, you might wonder...

Why does this happen?

It's because unlike the "triple equals" (===) which only checks if two values are exactly the same.

== does a lot of other things.

It handles functions, null, undefined, strings, and more with special rules.

Things get quite messy.

In fact, if you try to write a function that performs the same operation as ==, it might look something like this:

javascript
function isEqual(x, y) { // If `==` were a function if (typeof y === typeof x) return y === x; // Treat null and undefined as equal var xIsNothing = (y === undefined) || (y === null); var yIsNothing = (x === undefined) || (x === null); if (xIsNothing || yIsNothing) return (xIsNothing && yIsNothing); if (typeof y === "function" || typeof x === "function") { // If either value is a string // Convert the function to a string and compare if (typeof x === "string") { return x === y.toString(); } else if (typeof y === "string") { return x.toString() === y; } return false; } if (typeof x === "object") x = toPrimitive(x); if (typeof y === "object") y = toPrimitive(y); if (typeof y === typeof x) return y === x; // If x and y are not numbers, convert them to numbers if (typeof x !== "number") x = +x; if (typeof y !== "number") y = +y; // Actually, the real `==` is more complex, especially in ES6 return x === y; } function toPrimitive(obj) { var value = obj.valueOf(); if (value !== obj) return value; return obj.toString(); }

What does this mean?

It means == is complex.

Because it's complex, it's hard to know what happens when you use it.

This means you might encounter bugs.

The moral of the story is...

Simplify your life.

Use === instead of ==.

The story ends.

2024年6月29日 12:07 回复

The strict equality operator (===) does not perform type coercion, whereas the abstract equality operator (==) does. For ===, the types must be identical for the values to be considered equal.

Reference: JavaScript Tutorial: Comparison Operators

After any necessary type coercion, the == operator compares for equality. It does perform coercion, so if the values are different, it simply returns false. Both operators are equally fast. === returns false.

Quoting Douglas Crockford's excellent JavaScript: The Good Parts:

JavaScript has two sets of equality operators: === and !==, and their evil twins == and !=. A good product works as you expect. If both operands have the same type and value, === returns true and !== returns false. When the operands have the same type, the evil twins do the right thing, but if they have different types, they attempt to coerce the values. Their rules are both complex and hard to remember. Here are some interesting cases:

shell
'' == '0' // false 0 == '' // true 0 == '0' // true
shell
false == 'false' // false false == '0' // true
shell
false == undefined // false false == null // false null == undefined // true
shell
'

' == 0 // true

Equality Comparison Table

The lack of transitivity is shocking. My recommendation is never to use the evil twins. Instead, always use === and !==. All the comparisons shown above return false with the === operator.


Update

@Casebash raised a good point in comments and @Phillipe Laybaert's answer about objects. For objects, == and === behave consistently (with exceptions).

shell
var a = [1,2,3]; var b = [1,2,3]; var c = { x: 1, y: 2 }; var d = { x: 1, y: 2 }; var e = "text"; var f = "te" + "xt"; a == b // false a === b // false c == d // false c === d // false e == f // true e === f // true

Special cases occur when comparing a primitive with an object that evaluates to the same value due to its toString or valueOf methods. For example, consider comparing a string primitive with a string object created using the String constructor.

shell
"abc" == new String("abc") // true "abc" === new String("abc") // false

Here, the == operator checks the values of the two objects and returns true, but === finds that their types differ and returns false. Which is correct? It depends on what you're comparing. My recommendation is to avoid this issue entirely by not using the String constructor to create string objects from string literals.

Reference https://262.ecma-international.org/5.1/#sec-11.9.3

2024年6月29日 12:07 回复

你的答案