JavaScript comparison operators: Identity vs. Equality
Asked Answered
C

4

22

I've been trying to understand the difference between JavaScript's comparison operators: identity and equality. From what I've read, if you check the equality of two objects using ==, JavaScript will try to figure out if they are the same type and, if not, try to get them to that same type. However, === doesn't behave in the same manner. So as an example:

var n = "1";
console.log(n==1);        // outputs true
console.log(n===1);       // outputs false

So what is the difference between these "identity" operators and the regular equality operators? What is the benefit of having both?

Are there differences in performance? I would think that the identity operator would be faster since it doesn't do conversion.

Also, how do these differ when it comes to more complex objects, like arrays? Most importantly, what do conventions say about when one should be used over the other, why?

Counterblast answered 27/3, 2011 at 3:34 Comment(1)
Here I provide a truth table for the equal operator in JavaScript #359994Sharenshargel
A
34

The equality operator will attempt to make the data types the same before making the comparison. On the other hand, the identity operator requires both data types to be the same as a prerequisite.

There are quite a few other posts out there similar to this questions. See:

How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ? (has a nice comparison chart)
Which equals operator (== vs ===) should be used in JavaScript comparisons?

In practice, the identity operator comes in really handy when you want to be certain that a boolean value is true or false since...

1 == true     => true
true == true  => true
1 === true    => false
true === true => true
Alagoas answered 27/3, 2011 at 3:49 Comment(0)
S
17

The difference is that ==, <=, >= and != will do type coercion — for example, force a string to be evaluated as a number. ===, <==, >==, and !== will not do type coercion. They will compare a string to a number, and since the string "1" is not the same as the numeric value 1, the result is false.

Reference is here:
https://developer.mozilla.org/en/JavaScript/Reference/Operators/Comparison_Operators

Sedition answered 27/3, 2011 at 3:44 Comment(7)
Got it... so it is as simple as I outlined above. The identity operator doesn't check for type but the equality operator does.Counterblast
As for when to use which one; Douglas Crockford: It is almost always better to use the === and !== operators. The == and != operators do type coercion. In particular, do not use == to compare against falsy values.Philipps
@Joel... awesome link! Thanks! However, it doesn't list <== and >==. Are those legit?Counterblast
@no.good.at.coding: Crockford is dogmatic, and in this case wrong. In a case where both operands are guaranteed to be of the same type (for instance, in a typeof comparison such as typeof foo == "undefined") there is absolutely no advantage in using === over == since they are specified to use precisely the same steps.Doorstop
@Tim Down, in your example, it's unnecessary, but is it wrong? Is there a disadvantage to using === anyway? Outside of this example, the only one I can think of is forcing explicit casts/coercion.Plangent
@hyperslug: There's no disadvantage to using === other than using an extra character, but I disagree with not using it being labelled a stylistic error.Doorstop
But '<==' and '>==' don't exist.Lambart
L
12

== is the same things as ===, except that == does type conversion

To show you what I mean here is a JavaScript function that behaves exactly like ==:

// loseEqual() behaves just like `==`
function loseEqual(x, y) {
    // notice the function only uses "strict" operators 
    // like `===` and `!==` to do comparisons

    if(typeof y === typeof x) return y === x;

    if(typeof y === "function" || typeof x === "function") return false;

    // treat null and undefined the same
    var xIsNothing = (y === undefined) || (y === null);
    var yIsNothing = (x === undefined) || (x === null);

    if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing);

    if(typeof x === "object") x = toPrimitive(x);
    if(typeof y === "object") y = toPrimitive(y);

    if(typeof y === typeof x) return y === x;

    // convert x and y into numbers if they are not already use the "+" trick
    if(typeof x !== "number") x = +x;
    if(typeof y !== "number") y = +y;

    return x === y;
}

function toPrimitive(obj) {
    var value = obj.valueOf();
    if(obj !== value) return value;
    return obj.toString();
}

This function should help explain why people keep saying you shouldn't use ==.

As you can see == has a lot of complicated logic for type conversion. Because of that it's hard to predict what result you are going to get - and that can lead to bugs.

Here are some examples of some results you wouldn't expect:

Unexpected Truths

[1] == true // returns true
'0' == false // returns true
[] == false // returns true
[[]] == false // returns true
[0] == false // returns true

'\r\n\t' == 0 // returns true

Unexpected Conclusions

// IF an empty string '' is equal to the number zero (0)
'' == 0 // return true

// AND the string zero '0' is equal to the number zero (0)
'0' == 0 // return true

// THEN an empty string must be equal to the string zero '0'
'' == '0' // returns **FALSE**

Objects with Special Functions

// Below are examples of objects that
// implement `valueOf()` and `toString()`

var objTest = {
    toString: function() {
        return "test";
    }
};

var obj100 = {
    valueOf: function() {
        return 100;
    }
};

var objTest100 = {
    toString: function() {
        return "test";
    },
    valueOf: function() {
        return 100;
    }
};

objTest == "test" // returns true
obj100 == 100 // returns true
objTest100 == 100 // returns true

objTest100 == "test" // returns **FALSE**
Lelahleland answered 9/8, 2016 at 17:21 Comment(0)
H
0

The equality and identity operators are of particular note. The equality operator will attempt to coerce (convert) operands to the same type to assess equality. This is a handy feature, as long as you are aware it is happening. This block of code shows the equality operator in action.

let firstVal = 5;
let secondVal = "5";
if (firstVal == secondVal) {
console.log("They are the same");
} else {
console.log("They are NOT the same");
}

The output from this script is as follows:

They are the same

JavaScript is converting the two operands into the same type and comparing them. In essence, the equality operator tests that values are the same irrespective of their type.

If you want to test to ensure that the values and the types are the same, then you need to use the identity operator (===, three equal signs, rather than the two of the equality operator)

let firstVal = 5;
let secondVal = "5";
if (firstVal === secondVal) {
console.log("They are the same");
} else {
console.log("They are NOT the same");
}

In this example, the identity operator will consider the two variables to be different. This operator doesn’t coerce types. The result from this script is as follows:

They are NOT the same

Hensley answered 25/10, 2020 at 17:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.