JavaScript Programming Practices – Is a JS Boolean Having Custom Properties a Bad Practice?

coding-standardsjavascriptprogramming practices

In JS you can return a Boolean having custom properties. Eg. when Modernizr tests for video support it returns true or false but the returned Boolean (Bool is first class object in JS) has properties specifying what formats are supported. At first it surprised me a bit but then I began to like the idea and started to wonder why it seems to be used rather sparingly?

It looks like an elegant way of dealing with all those scenarios where you basically want to know if something is true or false but you may be interested in some additional info that you can define without defining a custom return object or using a callback function prepared to accept more parameters. This way you retain a very universal function signature without compromising capacity for returning more complex data.

There are 3 arguments against it that I can imagine:

  1. It's a bit uncommon/unexpected when it's probably better for any interface to be clear and not tricky.
  2. This may be a straw man argument, but with it being a bit of an edge case I can imagine it quietly backfires in some JS optimizer, uglifier, VM or after a minor clean up language specification change etc.
  3. There is better – concise, clear and common – way of doing exactly the same.

So my question is are there any strong reasons to avoid using Booleans with additional properties? Are they a trick or a treat?


Plot twists warning.

Above is the original question in full glory. As Matthew Crumley and senevoldsen both pointed it is based on a false (falsy?) premise. In fine JS tradition what Modernizr does is a language trick and a dirty one. It boils down to JS having a primitive bool which if set to false will remain false even after TRYING to add props (which fails silently) and a Boolean object which can have custom props but being an object is always truthy. Modernizr returns either boolean false or a truthy Boolean object.

My original question assumed the trick works differently and so most popular answers deal with (perfectly valid) coding standards aspect. However I find the answers debunking the whole trick most helpful (and also the ultimate arguments against using the method) so I'm accepting one of them. Thanks to all the participants!

Best Answer

In addition to the general design principles, like single responsibility, and least surprise, there's a JavaScript-specific reason that it's not a good idea: there's a huge difference between a boolean and Boolean in JavaScript that prevents it from working in the general case.

boolean is a primitive type, not an object, and cannot have custom properties. Expressions like true.toString() work because behind the scenes, it turns into (new Boolean(true)).toString().

Boolean (with a capital B) is an object, but has very few good uses, and being used as a boolean is definitely not one of them. The reason for that is, that every Boolean is "true", regardless of its value, because all objects get converted to true in a boolean context. For example, try this:

var answer = new Boolean(false);
if (answer) {
  console.log("That was unexpected.");
}

So, in general, there's no way to add properties to a boolean in JavaScript that still lets it behave in a logical way. Modernizr can get away with it because the only add properties to "true" values, which sort of work how you would expect (i.e. they work in if statements). If video isn't supported at all, Modernizr.video will be an actual boolean (with the value false), and can't have properties added to it.

Related Topic