Thoughts from the office by Ed Ball
Friday, February 18, 2005

In JavaScript, the “Boolean” operators && and || aren’t very Boolean at all. In most C-style languages, a || b returns a Boolean – true if either a or b are “true,” and false otherwise. (Remember that lots of things are “true” in JavaScript – in fact, the only things that are “false” are the false Boolean, the numbers 0 and NaN, the empty string, null, and undefined.)

Actually, that’s a somewhat simplified view, because the && and || operators of C-style languages short-circuit, meaning that b is not evaluated if a is “false.” Thus it is safe to have an expression like a == null || a.isEmpty() – the isEmpty method will not be called if a is null.

Where was I? Ah, yes, in most C-style languages, a || b returns a Boolean, so it’s the same as

a ? true : (b ? true : false)

But in JavaScript, a || b doesn’t necessarily return a Boolean, because it is really the same as

a ? a : b

How does this work? Well, if a is “true,” then a || b returns a, which is “true.” If a is “false” but b is “true,” then a || b returns b, which is “true.” If both a and b are “false”, then a || b returns b, which is “false.”

The danger is in assuming that a || b returns a Boolean when a and b are not Booleans themselves. For example:

var hasItems = a && a.getCount();
if (hasItems == true) // should be: if (hasItems)
  ...

Now, you shouldn’t be comparing Booleans to true or false anyway, but if you did, you’d find that hasItems equals true only when a.getCount() returns 1 (and then only because 1 equals true in JavaScript). Furthermore, hasItems equals false only when a.getCount() returns 0 (because 0 equals false). If a is null, hasItems will be null, which equals neither true nor false. If a.getCount() returns 2, hasItems equals 2, which, again, equals neither true nor false.

Be aware that the MSDN documentation is stunningly inaccurate here; it suggests that && and || always return true or false. (The JScript.NET documentation is more accurate, thankfully.)

Why does JavaScript evaluates the binary Boolean operators this way? Well, a || b provides a great shortcut for a ? a : b that only evaluates a once. Similarly, a && b provides a nice shortcut for a ? b : a. For example, instead of

var pane = null;
if (view != null)
  pane = view.getPane();

or

var pane = view == null ? null : view.getPane();

you can use

var pane = view && view.getPane();

You could argue that it’s not as clear, of course, particularly to anyone that doesn’t know about this feature of JavaScript, so take advantage of it at your own discretion.

I should also mention the unary Boolean operator of JavaScript. The “not” operator (!) is quite Boolean, because it always returns true or false. That is, !a evaluates to true if a is false, 0, NaN, "", null, or undefined; otherwise, !a evaluates to false. To explicitly convert a value to a Boolean, you could use a ? true : false, or you can simply use a double-not: !!a.

2/18/2005 4:45:39 PM (Pacific Standard Time, UTC-08:00) | Comments [0] | Code | JavaScript#
Search
Archive
Links
Categories
Administration
Blogroll