Ilia Choly
Ilia Choly

Reputation: 18557

using short-circuit operators to throw error - javascript

I know that jslint/jshint don't like it but I wanted to know if there were any real issues with doing something like.

var err = function(msg) { throw new Error(msg); };

Example 1: Assignment

var foo = bar.foo || baz.foo || err('missing foo property');

Example 2: Validation

typeof foo['bar'] !== 'string' && err('bar has to be a string');

Are there any gotcha's that I should be aware of?

Upvotes: 5

Views: 1301

Answers (5)

Matt Whipple
Matt Whipple

Reputation: 7134

As covered in the comments there is a strong chance of unexpected behavior due to JavaScript's loose interpretation of truthiness which is the driving force of the mentioned logical operators. As such there is a limited subset of conditionals in which the short circuit approach will be useful, and it therefore does not offer a consistent solution.

Out of the 2 examples given example 2 is a good application as it is a readable application of a test with very defined output. Example 1 however will cause issues if any of the attempted values evaluate to anything which may be valid in the program logic, but false from the perspective of the language. Applying a solution to these types of problems would effectively cancel out any benefit that the syntax could offer. Solutions for variations on these types of issues may not be consistent, and therefore this introduces a higher risk of bugs introduced at initial creation or any subsequent modifications.

Upvotes: 2

flavian
flavian

Reputation: 28511

Well, if you are particularly checking if the type is string, you are missing a big point. The raw type string has no methods.

var s = 'something';
console.log(typeof s);// outputs string

var s = new String('something');// same text as above
console.log(typeof s);//outputs object

JavaScript has a feature called auto-boxing. when you invoke string methods on variables declared in the first way, it will automatically switch from string to object string so the proper way to check for a string is:

isString = function (obj) { return toString.call(obj) === '[object String]';};

Triple equal(===) is used to quickly avoid undefined/null cases and common comparison pitfalls.

Other than that, you are fine. In production, you should also log your errors accordingly and use try catch blocks when you invoke throw functions.

Upvotes: 1

techfoobar
techfoobar

Reputation: 66673

Short circuiting the way you've shown in the question should be absolutely fine and imo preferred over elaborate if-else statements (of course the main condition you are checking should be correct in the first place, but that's not the topic here). In addition to more elegant looking code, you are essentially shaving bytes off of the total data the client has to download which is always good.

Upvotes: 1

Oleg V. Volkov
Oleg V. Volkov

Reputation: 22431

One of important things to consider is the precedence and interaction with some other operators. Incorrectly placed , or brackets can change flow in subtle and not-so-easily readable way. Otherwise it should be safe as long as you ensured that you intended logic matches shortcut rules. And of course, usual gotchas to what language consider truthly apply as well.

Upvotes: 1

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324690

As far as I'm aware, this is no more wrong than or die() in PHP. The short-circuit-ness of the operator is clearly-defined, so the error will only be thrown if the last case is reached.

Upvotes: 3

Related Questions