The CreatorCon Call for Content is officially open! Get started here.

SlightlyLoony
Tera Contributor

What do you suppose will be logged when you run the code below?


test(5, '05', 'numeric 5', 'string "05"');
test('5', '05', 'string "5"', 'string "05"');
test(5, 5, 'numeric 5', 'numeric 5');

function test(a, b, label_a, label_b) {
var equal = (a == b) ? 'equal' : 'unequal';
gs.log('Operands ' + label_a + ' and ' + label_b + ' are ' + equal + '.');
}

Were you surprised? Here's what's going on:

JavaScript defines equality (what you're testing with the "==" operator) roughly as "two things that have the same value". This can lead to unexpected results if you forget about Javascript's loose typing system and the consequent type coercsion. For example, consider what happens when JavaScript evaluates a statement like this:

5 == '05'

The JavaScript interpreter will see that the two operands are of different types (numeric and string, respectively) and it will coerce one of the operands into the type of the other (see "Coercion" for more details). In this case, it will coerce the string into a number, so the comparison is actually done with a numeric 5 compared to a numeric 5 and the result is true (since 5 does equal 5!).

Now check out this piece of code, and note the use of the "===" (what the heck is that?) operator:

test(5, '05', 'numeric 5', 'string "05"');
test('5', '05', 'string "5"', 'string "05"');
test(5, 5, 'numeric 5', 'numeric 5');

function test(a, b, label_a, label_b) {
var equal = (a == b) ? 'equal' : 'unequal';
var identical = (a === b) ? 'identical' : 'different';
gs.log('Operands ' + label_a + ' and ' + label_b + ' are ' + equal + ' and ' + identical + '.');
}

The "===" is called the identity operator. While the "==" operator tests for equal values, the "===" operator tests for identical values. Two values are identical if and only if both their type and their value is the same. One could say that identical values are more equal than merely equal values!

The identity operator is occasionally useful with primitive values, and much more frequently useful with JavaScript objects (whether built-in or ones you build yourself). That's because objects are only identical if they are the same instance of the object. Consider:

var x = {x:5};
var y = {x:5};
test(x, y, 'x', 'y');
test(x, x, 'x', 'x');
y = x;
test(x, y, 'x', 'y');

function test(a, b, label_a, label_b) {
var equal = (a == b) ? 'equal' : 'unequal';
var identical = (a === b) ? 'identical' : 'different';
gs.log('Operands ' + label_a + ' and ' + label_b + ' are ' + equal + ' and ' + identical + '.');
}

The first test of x and y shows the two are different, even though they have identical definitions. That's because they are two different instances of the same object that happen to have the same property and value. Note also that these show up as unequal. Surely they should evaluate to equal, since they have the same contents? Actually the equality comparison is undefined for objects in general (in JavaScript), so the value returned by the "==" operator should be treated as unknown, and you shouldn't write code that depends on it.

In the second test (comparing x with x), the results show the two are identical, as well they should be: x and x both refer to the same object instance, of course. But did the result of the third test surprise you? x and y are now identical because by assigning x to y, we've made both x and y refer to the same object instance...