Logical AND (represented as &&) and logical OR (represented as ||) are interesting critters in Javascript. You can get along for weeks, months, or even years without ever knowing the subtle nuance I'm going to discuss in this post. If your background is... well, pretty much any other language on the planet (and especially a compiled one), then chances are you've used Logical AND/OR like this:
{
// x is greater than 5 and less than 10
}
But I'm guessing you probably haven't ever used it like this:
{
name = name || 'Whoever you are';
alert('Hi there ' + name);
}
What's going on here? Isn't the result of a Logical AND/OR a boolean value?
Read on to learn more.
In Javascript, Logical AND/OR don't always return true or false. In fact, it wouldn't be inaccurate to say that they never intrinsically return true or false.
Here are the two basic rules:
- For Logical AND (&&): Javascript returns the first value that is "false-like", or the last value, if no values are "false-like".
- For Logical OR (||): Javascript returns the first value that is "truth-like", or the last value, if no values are "truth-like".
What is "truth-like"? It's any value in Javascript that, while not explicitly true, evaluates to true when used in an expression. This would be essentially anything that isn't "false-like" (more on that in a moment). Examples include:
- 5
- 'Steve'
- new Object()
- {}
The list goes on infinitely.
A "false-like" value is any value that evaluates to false in an expression. I think most people are pretty familiar with this one. It's precisely because of this that statements like:
actually work. The value of myDiv.addEventListener is neither true nor false, but it will treated as a "truth-like" or a "false-like" value, depending on whether or not the browser in question supports it.
"False-like" values include:
- null
- undefined
- ''
- ""
- 0
- NaN
Now, you can get along (presumably forever) without actually ever understanding the subtlety with which Javascript treats Logical AND/OR. Chances are you're going to end up with just the results you expect (especially if you restrict your use to if-conditionals). But, if you happen to know Javascript's unique handling of Logical AND/OR (and now you do), you can leverage it to slim down your code and, in some cases, make it more elegant.
We've already seen on example of this back at the beginning of this post. We leveraged Logical OR to provide a default value for a function parameter. This is definitely one of my favorite techniques. Not only does it cut down on the amount of code you need to write, but it reads really well to. When I see something like this:
I read that as: "x will be equal to n (if n is a valid value) or 100 (if n isn't valid)."
The real-world use for leveraging Logical AND in this way is probably a lot less. I can't think of too many scenarios in which you'd want the value of some variable to be the first "false-like" value in a list of values. I suppose you could use it to control program flow as in:
{
alert('Aluminum Monkeys Festering!');
}
var x = 5;
x && foo();
In the above example, the foo() function will execute, if x is "truth-like" (which it is in this case). The problem is, you generally want to execute a function conditionally, based on some much more specific proposition (i.e. x > 0). You can't get anything that specific from Logical AND. In this example, foo() would execute if x were any of: 'Steve', {}, -1, 0.04 (and of course, any other "truth-like" value).
My recommendation would be to simply understand how Javascript treats Logical AND, but I wouldn't recommend trying to leverage it as a "short cut" -- it'll probably just make things more confusing. When it comes to short cuts, stick with using Logical OR to provide default values for function parameters.
Of course, if anyone does know of a way to leverage Logical AND to do something creative and/or elegant, I'd love to hear it. Feel free to send me your comments.
5 Responses
See the ?? operator in C# for a similar language feature.
Thanks Rich! I wasn't aware of that; it's good to know.
very interesting, but I don't agree with you
Idetrorce
You can use the && construct to avoid a chain of null checks to get the last node or last value in a chain of references.
Consider this code:
// get the value of x.y.z
var value = x && x.y && x.y.z;
instead of:
var value = ( null == x ? null : ( null == x.y ? null : x.y.z ) );
Scott:
Valid point. I've actually done that on one or two occasions, violating my own recommendations.
In that one limited case, I think using logical AND as a shortcut is probably okay.
Thanks for the suggestion.