ariya.io About Collections Archives

Polluting and Unused JavaScript Variables

4 min read

There are two common mistakes when handling JavaScript variables, accidentally making a variable global and declaring a variable which is never used anywhere. Many well-known code linters can warn the developers when those cases are observed. How does the detection process actually work?

(The leakage sign was made by Robert Ingil)

Global Pollution

Let us see the first one, the case of global pollution. A code fragment which demonstrates the issue follows:

var height;
// some fancy processing
heigth = 200;

Due to a spelling mistake, the value is assigned to some variable different that what it is declared in the first line. Checking for this case is rather easy. As long as we get the AST (abstract syntax tree) of the code, we can look for such an assignment. The syntax tree itself is relatively trivial to obtain, we just pass the code to a parser like Esprima. Walking the syntax tree, we keep track of variable declaration so that we can cross-reference it within any assignment (of course, we must take into account complications such as variable hoisting and function scope). In fact, there is a tool that does these verification steps, it’s called leaky, made by David Bj√∂rklund. It must be used with Node.js and the package can be installed easily with

npm install leaky

The above mentioned logic, along with the syntax tree traversal, is less than 100 lines. Running leaky with the previous example code gives this output:

test.js:3
heigth = 200;
^
LeakError: global leak detected: heigth

If you develop an application or a library, this leak detection is suitable to be inserted in your testing workflow. A non-zero exit code is used to indicate that there is something wrong. Thus, the test section in your package.json could be something like:

"scripts": {
  "test": "leaky mycode.js && node run-tests.js"
}

If you update your code and it unintentionally leaks some variables, your test won’t even run as leaky will block further steps until the situation is resolved. Obviously, you could also plug the check as part of your git pre-commit hook.

Now, there can be few corner cases of global polluting which won’t be detected purely by static analysis. In that case, it is suggested to use strict mode so that such a pollution will be caught at run-time.

Unused Variables

For the second case, declaring a variable which is never used anywhere, the principle is surprisingly quite similar. Here we need to do the opposite because a variable needs to be marked as used if it is encountered in an expression. While we still need to traverse the syntax tree, it will require more steps as every possible usage of a variable, from the loop initializer to postfix operation, needs to be verified. All in all, the implementation won’t exceed 200 lines as demonstrated by the unused project from Tomaz Muraus and Roman Shtylman. Again, Node.js users can get the package easily via:

npm install unused

Running it on the previous code fragment shows before gives:

test.js
     height - on line 1

Most certainly, this tool can be used on a much more complicated code. In addition, an unused function argument can be valid, in particular when the function is part of the callback. For example, see the following block:

[4, 5, 6].forEach(function (value, index) {
    console.log(index);
});

In this case, value will be correctly reported as being unused. However, it is perfectly valid to keep it in that construct. Fortunately, unused can be invoked with an additional command-line parameter which would ignore specific argument (place)holders.

Just like leaky, it is perfectly reasonable to include unused as part of your development workflow, either within the test procedure or the pre-commit hook, or even integrating it as your editor’s behavior.

Try leaky and unused on your favorite application code and see if they show something interesting!

Related posts:

♡ this article? Explore more, check the archives, or follow me Twitter.

Share this on Twitter Facebook Google+

comments powered by Disqus