== (double equal) is also referred as loose equality. It allows coercion when comparing two values for equality
14 == '14' //true
=== (triple equal) is also referred as strict equality.It does not allow coercion.
14 === '14' //false
== VS ===
It is a misconception that double equal operator checks for value only and triple equal operator checks for value and type. They both checks for type. (Refer to spec 7.2.14Abstract Equality Comparison)
"donut" == "donut" //true "donut" === "donut" //true
double and triple equal operator behaves exactly same when when types match because spec says when types are same double equal returns the result of triple equal comparison (strict equality comparison)
Before we discuss, double and triple equal operator, understand this:
Primitive Values
Undefined, Null ,Boolean, Number,String, Symbol and BigInt
Data Types
Undefined, Null, Boolean, Number, String, Symbol, BigInt and Object. Data type of value can be identified by typeof operator.
There are 3 types of coercion: Number, String and Boolean.
Number Conversion
Number(undefined) //NaN Number(null) // 0 Number(true) // 1 Number(false) // 0 Number(NaN) // NaN Number('44') // 44 Number('apple') // NaN Number("") // 0 Number([]) // 0 Number([44]) // 44 Number(["44"]) // 44 Number(["1","2"]) // NaN Number(["apple"]) // NaN Number({}) // NaN Number(Symbol()) // throws TypeError
String Conversion
String(undefined) // "undefined" String(null) // "null" String(true) // "true" String(false) // "false" String(NaN) // "NaN" String(44) // "44" String([]) //"" String(["44"]) // "44" String(["44","apple"]) //"44, apple" String({}) // "[object Object]"
Boolean Conversion
Boolean(undefined) // false Boolean(null) // false Boolean(false) // false Boolean(true) // true Boolean(“44”) // true Boolean(“”) // false Boolean(44) // true Boolean(0) // false Boolean(-0) // false Boolean(NaN) // false Boolean([]) // true Boolean(["44"]) // true Boolean(["44","apple"]) // true Boolean({}) // true Boolean(Symbol()) // true
There are six falsy values: undefined, null, false, “”(empty string), 0(number zero) and NaN.
Double equal comparison (Abstract Equality Comparison)
It prefers to do numeric comparison. If one variable is number and other variable is string or boolean, it coerces string and boolean to number.
44 == "44" // true // "44" is coerce to number and compared true == 1 // true false == 1 // false
Here boolean value is coerced to number and compared.
If one variable is either number, string, or symbol and other is object, it turns object(non primitive value) to primitive by invoking toPrimitive abstract operation.
"apple" == {a: "apple"} //false "apple" == String({a: "apple"}) // [object Object] "apple" == [object Object] // false
Here object is coerced to string and compared.
44 == [44] //true 44 == Number[44] //44 44 == 44 //true
Here array is coerced to number and compared.
"44" == true //false Number(44) == Number(true) 44 == 1 //false
Here string and boolean are coerced to number and compared.
null and undefined
undefined == undefined //true undefined == null //true null == null //true null == undefined // true
Null and undefined are only true to themselves and each other. They will return false if compared to other value.
NaN
NaN == NaN //false
Any value is compared to NaN including NaN itself returns false.
Triple Equal Operator(Strict Equality Comparison)
If you compare value of different type, it will return false.
If type is same but value is different, it will return false.
"44" === 44 //false
(different type)
"batman" === "superman" //false
(same type but different value)
44 === 44 //true
(same type and value)
null === undefined //false
(different type but returns true in double equal comparison)
NaN === NaN //false
(Any value compared to NaN always return false including itself)