Impossible Equalities - a JavaScript puzzle |
Written by Ian Elliot | |||||||
Page 2 of 2
SolutionThere 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. PatternAt 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"); 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.
More Puzzles
<ASIN:059680279X> <ASIN:0470526912> <ASIN:1590597273> <ASIN:0596806752> |