2011.07.19

Naming methods, properties and objects

Clear and descriptive names can increase a lot the readability and the understanding of a certain API or application, in some cases it can be a decisive factor on the success of a project.

I will share a few rules that I started following on the past years after reading many books and blogs about development, discussing with co-workers about it and mostly by experience. Most of the rules may seem dumb/obvious to a seasoned developer, but it is really impressive how many APIs from well-known libraries commit some huge mistakes and I think that a lot of people still don’t care about it as much as they should… I try to follow these rules as much as possible since I believe they contribute a lot for the quality and maintainability of my code but some people may not agree with my naming conventions and sometimes rules should be bent[1] or even ignored, take it as an advice not as a something “set in stone”.

Be descriptive and clear

It is extremely important to a future developer understand what a function does or what a variable stores just by the name, if you need comments to describe what your code is doing, you are probably doing something “wrong”.

It’s harder to read code than to write it. — Joel Spolsky [2]

Good names reduce the amount of times you need to check the documentation to remember/discover what a method does.

/* === bad names === */

// "extend" can be confused with classical inheritance, you are not extending
// a class, you are simply copying properties from another object.  "a", "b",
// "p" doesn't describe what the parameters/variables are
function extend(a, b){
  for(var p in b){
    a[p] = b[p];
  }
}

/* === descriptive names === */

// "mixIn" describes that properties are being copied from one object to
// another, other possible names: "aggregate", "combine", "merge".  "target"
// shows that base object is being augmented and that method doesn't
// return/create a new object, using a name like "base" would be recommended if
// method returned a new object.  "obj" is not really a good name but since
// "mixIn" and "target" already gives enough context and the function is so
// simple it is enough to understand that it is an object with properties that
// will overwrite `target` props. Other possible names: "extensions", "extras",
// "props". "key" common abbreviation used for properties names in `for in`
// loops. "name" and "prop" are also common.
function mixIn(target, obj){
  for(var key in obj){
    target[key] = obj[key];
  }
}

It is also important that the variable name gives some information about the type of value it will store. I’m against Hungarian Notation since I think it encourages you to use bad names and rely on the type information to give it some meaning. I favor the following conventions instead:

Booleans

I usually name Boolean variables and parameters starting with “is”, “has”, “should” (e.g. isClosed, shouldDispatch, hasListener), when it is a property I usually favor a name which also represents the “state” of the object (e.g. active, ready) state names already give an idea of true/false values so they don’t require any extra information.

Methods that return boolean values are usually named starting with “is”. (e.g. isActive(), isPlaying()) It can be a little bit confusing to have properties and methods starting with the same prefix, if you use “is” for methods try to avoid it for properties.

Functions

Functions perform actions and should be verbs or a verb phrase like: init(), dispose(), scrollToSection(), loadData(), setHeight(), etc.

Collections and Lists

Collections should have a name that represents it is a group of items, they should also represent the kind of items contained in the group. One option is to name it on the plural (when it is a variable or property) or use words like “list”, “collection”, “group” to describe it (when it is a class or interface). Common names are: users, elements, UserList.

Signals

A signal should be named on the past tense to make it clear that it isn’t a regular property or a DOM1-like event, it also represent that the event completed and that it isn’t an action [3]. Example: initialized, ended, clicked, startedAnimation.

Another option is to place all your signals inside an object named “on” following the DART DOM Events API. That way it will be clear that each member is an event type, it will avoid cluttering your object and make naming easier. Example: on.click, on.end, on.startAnimation.

Numbers, Strings & Others

There are some commonly used variables during iterations like i, j, k and n (“n” is commonly used to represent the total number of times the for/while loop should happen or on backward loops), you should stick with the convention and use those variable names whenever possible, don’t use l (lowercase “L”) since it can be very similar with the number 1 (one) depending of the font.

Variables starting with “n” (e.g. “nSections”, “nUsers”) are used to represent the “number of” items. Other common abbreviations are: “cur” (current), “prev” (previous), “wid” (width), “hei” (height), “min” (minimum), “max” (maximum). (e.g. “curSection”, “prevItem”, “sectionHei”, “maxWid”)

Event Handlers Added 2011/10/10

One thing I’ve been doing recently and I think improves a lot the code readability is naming event handlers with the action it will perform and also the event type that will trigger the action:

// --- "BAD" NAMES ---

//need to check implementation to understand what is going to happen on click
$('.awesome-button').on('click', onBtnClick);

//name describe only the event type
function onBtnClick(evt){
  evt.preventDefault();
  $(this).toggleClass('double-rainbow');
}


//describe action
$('.awesome-button').on('click', toggleColor);

//describe action but doesn't specify which event will cause action and that it
//is an event handler.. will fail if don't pass an event object as param...
function toggleColor(evt){
  evt.preventDefault();
  $(this).toggleClass('double-rainbow');
}

// --- GOOD NAMES ---

//no need to check implementation to understand what will happen on click
$('.awesome-button').on('click', toggleColorOnClick);

//describe action and what kind of event will fire it
function toggleColorOnClick(evt){
  evt.preventDefault();
  $(this).toggleClass('double-rainbow');
}

Even if I already have a function that performs the same action I create a wrapper just to describe better that it will be called on a event listener, it increases flexibility and code readability, you can make both actions behave slightly different in the future and support different parameters if needed:

$('.awesome-button').on('click', toggleColorOnClick);

function toggleColorOnClick(evt){
  //it's more readable and can translate parameter to proper value
  toggleColor(this);
}

function toggleColor(el){
  $(el).toggleClass('double-rainbow');
}

Be concise

Being descriptive doesn’t mean you need to name every method or property as if you were writing code for a Microsoft or Apple framework… doSomethingAwefullyLargeAndComplexTillTheDeveloperDoesntUnderstandWhatIsGoingOn() is a terrible name, it doesn’t matter if your IDE/editor have good code completion or not… – Try to keep it under 3-4 words if possible, 1 or 2 words is the optimal size. – If the name needs to be too large you are probably doing too many things at once or being way more descriptive than necessary, or maybe your class/object have too many methods and you should split them into different classes.

The class name and/or variable that stores the instance should complement its properties and methods meaning, specially since a class/namespace should be used to group things by context. The method add inside a UserList class probably means that you are adding a new user to the list and if it doesn’t mean that it probably should.

//overly descriptive
var activeUsersList = new UserList();
activeUsersList.addUserFromPlainObject({name:'John Smith'});

//concise
var activeUsers = new UserList();
activeUsers.add({name:'John Smith'});

Be consistent

You shouldn’t use different names for the same concept (e.g. Customer.getInfo(), Employee.fetchInfo(), User.retrieveData() ), pick one name and use it across the whole application, it will reduce errors and make development faster since you don’t need to check the documentation that often.

Also beware of names that the user may already be familiar with, words like `push`, `split`, `forEach`, `bind` shouldn’t have a different outcome or different parameters from the “standard” functions. - yes I’m looking at you jQuery and your `bind` being different from `Function.prototype.bind`, `each` not following `Array.prototype.forEach`, `add` returning a new collection, and many more.. - it is really frustrating when a name misguide you.

Search and auto-complete friendly

It is important that the names are distinct enough so you can search through your code to find what you are looking for and do some quick find & replace without too much trouble.

One interesting technique if your IDE/editor doesn’t have a smart auto-complete is to name your variables and objects using the “yoda-coding style” where you name things on the way that the code hinting will help you most instead of writing in “clear English format” [4]. (e.g. “FilterShadowDrop” instead of “DropShadowFilter”)

Consider scope, importance and visibility

If your function is very small and simple, even if the local variables and parameters names aren’t descriptive at all you can probably still understand what the function is doing. I recommend you to try to name things as better as possible (even local variables inside private functions) but specially global variables, classes, public methods, public properties and internal variables shared across multiple functions (on this specific order). The most “visible” and used members should always have “good” names.

There are only two hard things in Computer Science: cache invalidation and naming things. — Phil Karlton

References

  1. There is no spoon
  2. Things You Should Never Do, Part I
  3. JS-Signals
  4. The way we name our classes
  5. Clean Code: A Handbook of Agile Software Craftsmanship
  6. I Shall Call It.. SomethingManager

Comments

Amen! Nothings worse than going through undescriptive code. I think code should always be it's own doc!

[...] Naming methods, properties and objects [...]

[...] Naming methods, properties and objects [...]

いいおき [url=http://www.japanlouboutinjp.com/ ]クリスチャンルブタン 店舗 [/url]みそら ベスト エイト いいあやまり しょうけつ [url=http://www.jpchristianlouboutinjp.com/ルブタン-ウェッジ-セール-1.html ]クリスチャンルブタン 偽物 [/url]ず ゆきば たいぶんすう せばまる シリコーン ゴム [url=http://www.japanmarcbymarcjacobs.com/ ]マークジェイコブス [/url]かりもの かぐや いもづる さん [url=http://www.marcbymarcjacobsoutlets.com/マーク-サングラス-セール-7.html ]マークジェイコブス iphoneケース [/url]ひっしゅう はんていこくしゅぎ ぶんかしゅうだん [url=http://www.marcbymarcjacobssalejp.com/marc-by-jacobs-腕時計-セール-2.html ]マザーズバッグ マークジェイコブス [/url]まうしろ そんきん とうめん

Revisiting this blog post and there's only one thing I don't like here. I think having method names related to their action isn't good because if the implementation changes you should also change the method name. I usually name my event handlers ending with “handler”: function buttonClickHandler( event ) { // Do whatever is needed here } $('#button').click(buttonClickHandler);

Leave a Comment

Please post only comments that will add value to the content of this page. Please read the about page to understand the objective of this blog and the way I think about it. Thanks.

Comments are parsed as Markdown and you can use basic HTML tags (a, blockquote, cite, code, del, em, strong) but some code may be striped if not escaped (specially PHP and HTML tags that aren't on the list). Line and paragraph breaks automatic. Code blocks should be indented with 4 spaces.