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)
ntimes. But how well this can be done depends on the language used..eachis a predicate (returns a boolean). The documentation says that function is a callback. Yeah, I guess I don't understand how that works.