Avoid `void 0`

- - | Comments

I came across some code recently that looked like this:

1
2
3
4
5
6
function clearPhoto(photo) {
   photo._id = void 0;
   photo.name = void 0;
   photo.caption = void 0;
   photo.renditions = void 0;
}

While it’s definitely worthwhile to know what void 0 does, in JavaScript, just use undefined instead of void 0. There are a few reasons why some might consider using this in your codebase, and I’d like to address a few of them here.

1. Defensiveness

A very old version of JavaScript does allow for assigning to the identifier undefined and that’s potentially an argument for why void 0 should be used instead of undefined. Formally, the undefined that we use in JavaScript is a property on the global object. In the browser, window.undefined is similar to window.setTimeout It is assignable in ES3, so you can change the value of undefined in old browsers. Understandably, everyone is worried about what happens if someone sneaks undefined = true somewhere into your codebase, but there are other ways to deal with this problem.

Why not worry about the assignment problem?

  1. All modern browsers provide ES5, the version of JavaScript that fixes the assigning undefined problem, by making sure that trying to assign undefined is a no-op.
  2. Ideally, your entire codebase should be in Strict Mode, and ES5 strict mode does not allow assigning to non-writeable properties, which will mean that an error is thrown if someone accidently assigns to undefined.
  3. Whatever linting tool that you use should have an option to flag accidental things like this with nice early error messages.

2. Expressiveness

Depending on the developer’s programming language background, some devs feel like using void 0 expresses their intent clearer. They want to ‘void out’ a certain property in a similar way to how programming languages like C have a void return type if they don’t return anything. Personally, I have a hard time understanding how the word “undefined” can be better expressed considering there’s only one actual regular dictionary definition of the word, but everyone has different tastes when it comes to these things.

With respect to this argument, I always err on the side of idiom and convention. JavaScript uses the identifier “undefined” for this meaning, void 0 and I think that it only sounds better if you’re coming from C/C++.

3. The tendency to show off

I know that I’m veering into difficult territory here, but I think that a part of this is showing off. We all have the urge to use everything new that we learn in a programming language and we all have egos. This particular case is even better because many JavaScript developers don’t know what void 0 does, or even that there is a void operator in JavaScript.

There’s also a tendency to think “Well, it’s part of JavaScript and if developers don’t know JavaScript, then why are they working here?” I understand that argument too, but I don’t think that it is always correct. I very unscientifically polled my twitter followers and the people who saw their retweets to figure out how many people actually knew what void 0 actually did. Only 65% of responses were correct, and taking into account cheating and the already JS-loving skew of my follwers, the actual percentage of JavaScript developers that know what void 0 does is much lower.

I know that thinking about what most JavaScript developers already understand can be a slippery slope, but here’s a litmus test for when this should matter. If there is a straightforward and semantically equivalent alternative to sprinkling your codebase with little known constructs/features, don’t use it. undefined is that alternative whenever you think you need to use void 0. Please don’t think that I’m telling you not to use anything that’s not known by most JS devs. Getters and setters, for example, are fine because those are incredibly powerful and have no more widely known alternative.

Alternatives for the concerned

In case you are very worried about older browsers and malicious code, the way to deal with this is silo away somewhere in your code an actual unchangeable version of the value undefined and use that where you need it. Define it once and use it everywhere instead of void 0 everwyhere.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(function(){
'use strict';

var undefined = void 0;
// OR
var undefined = (function(){}).call();
// OR if jQuery's around
var undefined = jQuery.noop();
// OR if in node/browserify
var undefined = require('undefined');

// ...

function clearPhoto(photo) {
   photo._id = undefined;
   photo.name = undefined;
   photo.caption = undefined;
   photo.renditions = undefined;
}

})();

Summary

Please don’t use void 0 in code that other people need to read. If you’re worried about malicious code changing the value, there are alternatives. When trying to decide about what to include in your codebase, consider what percentage of people that work with you will understand what you’re doing and apply the litmus test of ‘Is there an equivalent alternative?’.

See you in the comments or on twitter!

In case you saw my twitter poll, here’s the result breakdown:

Comments