Wordsligner • Dissident • Webwright

If it quacks like a duck

Published 20 July 2008

I felt a bit elitist after posting about my desire that job candidates should have a low-level understanding of JavaScript. Today a bug I caught reinforced that belief.

JavaScript and Ruby are dynamic or [duck-typed][dt] languages, meaning that variable values are converted between types when your code requires, allowing you to do things like:

"2" * 2 == 4 // true

Instead of having to manually convert between types. This allows some shortcuts for otherwise annoying code. For example, you never have to do

if (typeof foo == 'undefined' ||
	foo === null ||
	foo === false ||
	foo === "0" ||
	foo === '') { doSomething();}

You can just do

if (foo) { doSomething();}

In JavaScript you can also do some nifty type conversion:

"4" * 1 // 4
4 + ""  // "4"
!! 4    // true

This can lead, however, to some odd bugs if you’re not careful. I was receiving a boolean flag via JSON, which came across the wire as zero or one. In my application I had something that was essentially

if (flag) { makeTheMagicHappen();}

Unfortunately, flag was coming in as a string, not an integer. I want flag as a Boolean, but "0" evaluates to true, so my flag was coming up incorrectly. Worse, this was a pretty tough bug to spot. The solution, of course, is:

if (Boolean(Number(flag))) { makeTheMagicHappen();}

or

if (!! (flag * 1)) { makeTheMagicHappen();}

Worse, type coercion varies between languages. Ruby converts all values except nil to true.

Notes

  1. Actually, the solution is to change the bad data, but for complicated reasons outside of this post’s scope, that’s not possible. [dt]: http://en.wikipedia.org/wiki/Duck_typing “Duck typing - Wikipedia, the free encyclopedia”