I used a technique in my code the other day to work around a browser issue. A colleague informed me during code review that the technique wasn’t immediately obvious and possible violated our “no clever code” standard. We kept it in for other specific reasons, but I wanted to take a moment to un-obfuscate the technique for others.
window.console while the developer tools are closed. Other browsers ignore the call (including other versions of IE), but version 9 will die gloriously.
The easiest fix is to, of course, not ship debugging calls in production code.
In situations where you absolutely need to leave this debugging code in place, however, it’s often useful to create your own version of the console logger if it doesn’t exist. Within a closure, I’ll sometimes place code like the following:
Inside the closure, this defines a local console object that will either default to the global one (if available) or a custom short-circuit. We’re using the falsey nature of
undefined here to provide the fallback, but this is not what I mean by variable coalescing.
The above approach works well for single scripts. If your application has multiple scripts (ideally inside separate closures), it becomes redundant as you need to repeat the same code inside every closure.
It’s an easy line of code to forget; particularly if you’re used to following the “don’t ship debugging statements” rule. Instead of building a short circuit, it’s often better to just check for the existence of the console object before using it.
window.console.log( 'some error.' )
This works, but turns every debugging line into 3. 1 The situation that warranted this change I mentioned above was in a vendor script, and I didn’t want to change the line numbering in the file. My change instead was to use:
Again, we’re using the falsey nature of
undefined to our advantage here. If the console object doesn’t exist, the
&& operation will prevent execution of the following statement. If the object is available, then the method call will fire as expected.
When I build tasks for WordPress’ CLI system, I use a similar approach. I usually create a
--verbose flag for my scripts that prints more detailed messages to the interface. Inside my script, this means I have to wrap calls to
WP_CLI::line in checks for whether or not the flag is set.
Using variable coalescing, my more verbose calls become:
When I add a progress bar to my scripts, I usually store it inside a variable called
$notify. Like the verbosity flag above, I can use variable coalescing to fire the progress bar only in situations where it actually exists:
Does this qualify as a clever trick? If I were the one who’d come up with it, I’d probably say “yes” just to appease my ego. I didn’t invent the technique, though, and from an outside perspective I don’t see it as being more clever than things like closures returning functions or type coercion in cache lookups.
It is, however, an underused technique that many could stumble over the first time they see it. That’s partly the reason I want to document both the technique and a couple of use cases here.
The more developers using a technique, the better the documentation around it becomes, and the easier it is to justify its use in your own code.
- Yes, you could put the entire conditional and brackets on one line, but that also violates coding standards and many formatting tools will automatically re-align things anyway. ↩