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:
- It's a bit uncommon/unexpected when it's probably better for any interface to be clear and not tricky.
- 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.
- 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
andBoolean
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 liketrue.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 aboolean
is definitely not one of them. The reason for that is, that everyBoolean
is "true", regardless of its value, because all objects get converted totrue
in a boolean context. For example, try this: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 actualboolean
(with the valuefalse
), and can't have properties added to it.