Saturday, July 19, 2014

08 - Comparison and Type Conversion

There are two comparison operators in JavaScript. One is ==, and the other is ===. The difference of these two operators is about type conversion. If two values in different types are compared with ==, they will be converted into the same type first and then compared. There is no type conversion when values are compared with ===.

Type Conversion with ==
Let's discuss how types are converted when they are compared with == one by one.  The first type is Boolean values false and true. When one operand of the == operator is a Boolean value and the other operand is an integer, the Boolean value false is converted to 0, and true is converted 1. When one operand of the == operator is a Boolean value and the other operand is a string, the Boolean value false is converted to "0", and true is converted "1", as demonstrated below:

console.log(false == 0);   // true
console.log(true == 1);    // true
console.log(true == 3);    // false 

console.log(false == "0"); // true
console.log(true == "1");  // true

When one operand of the == operator is a string and the other operand is an integer, the string will be converted to an integer value. Therefore, "3" == 3 gets true, as shown below:

console.log("3" == 3);      // true  

When a string is compared with a Boolean value, both an empty string and "0" are converted to false, "1" converted to true. Any other strings can neither converted to true, nor false.

console.log("0" == false);      // true
console.log("" == false);       // true
console.log("1" == true);       // true
console.log("2" == true);       // false
console.log("2" == false);      // false

console.log("true" == true);    // false
console.log("false" == false);  // false

It becomes complex when a string is used as a condition in an if expression. In such cases, only an empty string is treated as false, and all others are treated as true:

var valueFunction = function(name, str) {
    if(str) {
        console.log(name, "is true");
    }
    else {
        console.log(name, "is false");
    }
}

valueFunction("Empty string", "");  // Empty string is false
valueFunction("0", "0");            // 0 is true
valueFunction("1", "1");            // 1 is true
valueFunction("2", "2");            // 2 is true

Two special values null and undefined are equal to each other when compared with the == operator, but they are not equal to any other values:

console.log(null == undefined);  // true 

console.log(null == undefined);  // true  

console.log(null == false);      // false
console.log(undefined == false); // false
console.log(null == 0);          // false
console.log(undefined == 0);     // false
console.log(null == '');         // false

Even null and undefined are not equal to the Boolean value false, they are treated as false when they are used as conditions in if expressions:

var valueFunction = function(name, value) {
    if(value) {
        console.log(name, "is true");
    }
    else {
        console.log(name, "is false");
    }
}

valueFunction("undefined", undefined); // undefined is false
valueFunction("null", null);           // null is false

The behavior of NaN is also quite special, which does not equal to any values, including NaN itself:

console.log(NaN == 0);     // false  
console.log(NaN == 'NaN'); // false  
console.log(NaN == NaN);   // false 

When an instance of a reference type is compare with a value type, the instance will be converted by invoking valueOf method:

var a = "hello world";
var b = new String("hello world");
console.log(a == b); // true

When two instances of reference types are compared, they equal to each other only when they are the identical instance:

var a = [1, 2, 3];
var b = [1, 2, 3];
console.log(a == b); // false

var c = a;
console.log(a == c); // true;

Equality with the == operator is reflective, but not transitive. That's to say, if A == B, B == A. However, if A == B and B == C, it's not necessary A == C. The following is an example:

console.log("0" == 0);     // true
console.log(0 == "");      // true
console.log("0" == "");    // false

No Type Conversion with ===
When two values are compare with the operator ===, they equal to each other only when they are in the same type and their value are identical. That's to say, no type conversion is involved in === comparison. When two values are not in the same type, they don't equal to each other when they are compared with the === operator. Let's take the following piece of code as an example:

console.log(false === 0);        // false
console.log(true === 1);         // false
console.log("3" === 3);          // false

var a = "hello world";
var b = new String("hello world");
console.log(a === b);            // false

console.log(null === undefined); // false

All pairs of values are not equal when compared with the operator ===, and two values in a pair have different types. As we discussed before, every pair of values are equal when compare with the operator ===.

No comments :

Post a Comment