So I've read through Short circuit evaluation, is it bad practice?, Is it bad practice to use short-circuit evaluation instead of an if clause? and some other related questions, and I get that it is generally considered bad practice to use short-circuit evaluation for flow control.
I'm trying to write warning-free, ROC (Really Obvious Code), and I'm looking for the best way to do only the first of a number of actions that returns a truthy value.
The code I am refactoring from was originally like so:
this.initSingleTag(tags.open_at === '7', CombinedSearch.ITEMS.avail_morning, 'search-functions-open', 'morning') ||
this.initSingleTag(tags.open_at === '12', CombinedSearch.ITEMS.avail_midday, 'search-functions-open', 'midday') ||
this.initSingleTag(tags.open_at === '18', CombinedSearch.ITEMS.avail_evening, 'search-functions-open', 'evening') ||
this.initSingleTag(tags.open_at === '22', CombinedSearch.ITEMS.avail_late, 'search-functions-open', 'late');
Trying to get it free of warnings in JSHint, my first-run refactor looks like:
if (!this.initSingleTag(tags.open_at === '7', CombinedSearch.ITEMS.avail_morning, 'search-functions-open', 'morning')) {
if (!this.initSingleTag(tags.open_at === '12', CombinedSearch.ITEMS.avail_midday, 'search-functions-open', 'midday')) {
if (!this.initSingleTag(tags.open_at === '18', CombinedSearch.ITEMS.avail_evening, 'search-functions-open', 'evening')) {
this.initSingleTag(tags.open_at === '22', CombinedSearch.ITEMS.avail_late, 'search-functions-open', 'late');
}
}
}
Which honestly looks no more readable to me. Is there a common better practice for this kind of situation?
Edit: Since posting the question and headscratching a bit, I had come up with the following:
CombinedSearch.prototype.initFirstTruthyTag = function(tags) {
var that = this;
$.each(tags, function(i, parameters) {
return !(that.initSingleTag.apply(that, parameters));
});
};
...Later...
this.initFirstTruthyTag([
[tags.open_at === '7', CombinedSearch.ITEMS.avail_morning, 'search-functions-open', 'morning'],
[tags.open_at === '12', CombinedSearch.ITEMS.avail_midday, 'search-functions-open', 'midday'],
[tags.open_at === '18', CombinedSearch.ITEMS.avail_evening, 'search-functions-open', 'evening'],
[tags.open_at === '22', CombinedSearch.ITEMS.avail_late, 'search-functions-open', 'late']
]);
Although I am painfully aware of the fact that the third parameter is repeated multiple times, it's kind of a sideline to the original question (plus I am not sure that dogged compliance with DRY outweighs the consistency with the original function call, which is still used throughout the rest of the code around this call)