Twisted logic: understanding truthy and falsy
An upcoming article I'll be doing for Smashing Magazine will look at the oddities and gotchas of Javascript - and lordie does it have a few.
One of these is the concept of truthy and falsy. These are sort of like true/false-lite, which will anger you somewhat if you majored in logic or philosophy. You mean you didn't know true and false were in fact gradable, not absolute concepts!?
In Javascript, every value has an in-built flag denoting its boolean equivalent. This is called upon when you ask the value to behave like a boolean, e.g. by comparing it to a real boolean. Javascript coerces your value into a boolean, such that the comparison is possible (after all, you can't compare apples with pears). See below for more on data coercion. So:
1var someVar = 0;
2alert(someVar == false); //evaluates true
Since we are attempting to compare zero to a boolean, Javascript coerces the zero to its truthy/falsy equivalent - and zero is a falsy (along with null, undefined, NaN, empty strings and false - everything else is a truthy). So the expression effectively becomes:
alert(false == false); //evaluates true, of course
It's important to realise that this does not mean your value is a boolean - it simply means Javascript temporarily converts it to a boolean to make the comparison possible. If we did the same comparison with the === operator (which compares not only by value but also by type), the result would be different:
alert(someVar === false); //evaluates false - someVar is a number, not a legitimate boolean
It gets worse
Clear enough? It gets more complex.
A well known quirk of Javascript is that an empty array appears to be equal to false.
alert([] == false); //evaluates true
How can this be, if an empty array is a truthy? (it is often mistakenly stated as being a falsy).
Er, good question. This throws up an interesting point in Javascript: that testing values against booleans and testing them alone inside a condition, does not always return the same thing. Here's what I mean:
1alert([] == true); //evaluates false
2alert([]); //evaluates true - so an empty array is a truthy
Thus, the latter approach really shows what is and isn't a truthy/falsy.
Data coercion
As I touched on above, Javascript does what's called data coercion. It's important to understand this in order to properly understand truthy and falsy.
This might sound new to you, but chances are you've experienced it before. The most common example is when you output an array.
alert(['one', 'two', 'three']); //alerts('one,two,three');
You didn't ask Javascript to convert the array to a string - except you did, when you alerted it. An array cannot itself be output, so Javascript coerces it into its string format.
Internally, what happens here is it calls the array's toString() method, which in turn calls the join() method. Both of these are present automatically on every array, due to Javascript's prototypal inheritance. That's a separate blog post if ever there was one...
Avoiding coercion
If you want to be strict in your comparisons and avoid data coercion you should use the comparison operator ===, which compares not only value but also type.
Hope you found this helpful.
post a commentNew Smashing article by me on image manip
Those nice guys at Smashing Magazine have just posted up my latest article for them, on image manipulation in jQuery and PHP.
It serves to highlight just how well PHP (specifically, its GD library) and Javascript go together in forming interactive web aps.
Short of a little flaming for my less-than-superb filetype verification technique in the PHP, the article has been generally well received.
post a comment