Impossible Equalities - a JavaScript puzzle
Written by Ian Elliot   
Article Index
Impossible Equalities - a JavaScript puzzle
Solution

Solution

There are all sort of values that could have been used to create this behaviour. In general the non-strict equality operator doesn't obey the usual transitive law of equality. That is in the case of equality or any operator claiming to be an equivalence operator you expect that

if a=b and a=c then you can conclude that b=c

However for the non-strict equality operator you cannot make this assumption. That is

if a==b and a==c you cannot rely on b==c begin true.

In the case of our problem code the general situation was reduced to something more specific because the role of c  was taken as numeric zero i.e. c is set to zero giving:

if a==b and a==0 it is possible that b=0 is false.

For example, suppose a='0'  and b='' a null string then clearly

a==b

is false because as strings '0' isn't equal to '' a null string.

Now consider

a==0

As a is '0' a string that converts to zero when ToNumber('0') is called this expression is true after type conversion.

Slightly less obviously

b==0

is true because a null string has been defined as converting to zero i.e. ToNumber('') returns zero. You can confirm this by trying

alert(+'');

which displays zero.

The problem is the way that one too many strings type convert to zero - even though this behaviour can be useful when working with input boxes that have been left empty.

Pattern

At this point it is tempting to blame it all on the use of the non-strict equality operator but the conversion rules for strings to numbers is just as much to blame. In this case you probably don't want to consider a null string as being the same as a zero.

Simply swapping to the strict equality operator brings other problems with it and isn't entirely trouble free. For example if a and b are set to different objects then a===b is false even in some situations where you might want to regard the two objects as equal - e.g. string objects wrapping the same string litteral.

If you want to be sure of what is happening then it is usually best to make explicit conversions. 

For example you might write:

if(Number(a)==Number(b))alert("a equals b");
if(Number(a)==0)alert("a is zero");
if(Number(b)==0)alert("b is zero");

In this case the use of == is transitive and even if a='0' and b='' you will find that 'a equals b', 'a is zero' and 'b is zero'. The reason is that the same conversion is performed for each comparison.

JavaScript makes some conditionals easier to write and some more difficult. The real point, however, is that in an object-oriented world comparisons are inherently tricky and you always need to be very clear about what you are comparing with what and what type conversions are used in the comparison.

 

Banner

More Puzzles

C#
In-Place Or Operator Methods?

This particular C# puzzle is one of those that involves an error that no self respecting programmer would make... but are you so sure. If you use the DateTime class regularly then sure, you not only w [ ... ]


Javascript
The Undefined Defined Variable

Here's a teaser that poses a practical problem - one that's happened in everyday Javascript programming. See if you can work out the answer before looking at its solution and the pattern to follow to  [ ... ]


Javascript
Stringy Objects

A Programmer's Puzzle in which we contemplate situations in which string equivalence in Javascript is clearly not what it seems - and explain why it all goes wrong.


Other Articles


<ASIN:059680279X>

<ASIN:0470526912>

<ASIN:1590597273>

<ASIN:0596806752>