When I joined Caplin 10 years ago I came from a company that used Hungarian notation to name its C++ and Visual Basic variables. For me, it seemed a natural progression to continue to use these naming conventions and adapt them to be suitable for the JavaScript code that I now writing.
The evolution of software practices ebbs and flows over time, and it seems that Hungarian notation is currently out of favour. This is especially apparent with some of the new developers that have joined the team here at Caplin. One of the first questions they ask is often about the naming convention that we use.
Hungarian Notation is useful in JavaScript
I believe that an untyped language like JavaScript benefits greatly from Hungarian notation, allowing the intended type of a variable to be determined from its name. If I am debugging some code that is going wrong I can quickly check that the data associated with that variable is of the expected type. Also if I am writing new code I know which methods I can invoke on the variable.
The scoping within JavaScript is strange too. If a developer forgets to add a var
declaration for a particular local variable within a function then the variable is added to the global scope, with the potential of nasty unforeseen side effects.
Caplin’s JavaScript Naming Convention
At Caplin, we have two components that are added to the start of the names of our JavaScript variables: one represents the type, and the other represents the scope.
Type Prefix
b
– a Boolean variable. We only expect it to have a valuetrue
orfalse
. For examplebIsVisible
.e
– a DOM element. Provided its notnull
we expect to be able to accesschildNodes
and so on. For exampleeGridBody
.f
– a function pointer. Typically this will be invoked at some stage in the future. For examplefCallback
.m
– a map. For examplemPropertyNamesToValues
.n
– number, either a integer or a float. For examplenColumnIndex
.o
– an object. We don’t try to differentiate between all the different object types we have defined within our code with dozens of different prefixes, this would get too complicated to remember. Typically we use JsDoc to identify the types, if the scope of a variable is not small enough to see its type. For exampleoObservable
.p
– an array. This should really use ana
prefix, however this is a throw back to the original Hungarian notation from my C++ days where an array was just a pointer. For examplepQueue
.s
– a string. Provided its notnull
we expect to be able to invoke methods likematch()
. For examplesUsername
.v
– a variant, where various different types might be allowed. A typical example of where this might be used is a generic debugging method that is happy to take any type of argument and output it to a log. For examplevValueToLog
.
Scope Prefix
m_
– private member variable. Although there are techniques to hide member variables there are performance costs associated with them. Them_
prefix is a gentle reminder that only the class the member variable is defined in should be accessing it. In fact, when the code is obfuscated these private members may also be obfuscated since they aren’t part of of the public interface of the class. For examplethis.m_sSubject
.g_
– global variable. These are used sparingly. If a variable has a value to assigned to it within a method but does not have a g_ prefix then beware, this is probably a mistake and we now have an unexpected side effect. For exampleg_bIsDevelopment
.- All other variables, such as local variables or function arguments, have no scope prefix.
Horses for Courses
To be honest, although I use Hungarian notation throughout all of my JavaScript code, I avoid it altogether when coding in other languages such as Java. The reason for this is simply that Java is a typed language, and I don’t feel that this adds any benefit, however Joel Spolsky makes a great case for using it, even in the case of a typed language, in his blog Making Wrong Code Look Wrong.