This is a pretty common and useful practice:
// default via value
var un = undefined
var v1 = un || 1
// default via a function call
var myval = () => 1
var
As other answers have stated, it is because throw
is a statement, which can't be used in contexts which expect expressions, such as on the right side of a ||
. As stated by others, you can get around that by wrapping the exception in a function and immediately calling it, but I'm going to make the case that doing so is a bad idea because it makes your intent less clear. Three extra lines of code is not a big deal for making the intent of your code very clear and explicit. I personally think that throw
being statement-only is a good thing because it encourages writing more straightforward code that is less likely to cause other developers to scratch their heads when encountering your code.
The ||
defaulting idiom is useful when you want to provide default or alternative values for undefined
, null
, and other falsy values, but I think it loses a lot of its clarity when used in a branching sense. By "branching sense", I mean that if your intent is to do something if a condition holds (the doing something in this case being throwing an exception), then condition || do_something()
is really not a clear way to express that intent even though it is functionally identical to if (!condition) {do_something()}
. Short-circuit evaluation isn't immediately obvious to every developer and ||
defaulting is only understood because it's a commonly-used idiom in Javascript.
My general rule of thumb is that if a function has side effects (and yes, exceptions count as side effects, especially since they're basically non-local goto statements), you should use an if statement for its condition rather than ||
or &&
. You're not golfing.
Bottom line: which is going to cause less confusion?
return value || (() => {throw new Error('an error occurred')})()
or
if (!value) {
throw new Error('an error occurred')
}
return value
It's usually worth it to sacrifice terseness for clarity.