DEV Community

Cover image for Stop Using "data" as a Variable Name
Devin Witherspoon
Devin Witherspoon

Posted on • Edited on

Stop Using "data" as a Variable Name

"There are only two hard things in Computer Science: cache invalidation and naming things."

- Phil Karlton

Setting aside cache invalidation, which is indeed difficult, this infamous quote is something that rings in my head whenever I'm having trouble finding the right name for something. Clear naming provides important context whenever someone needs to quickly understand code, whether they're firefighting, debugging, interviewing, or assisting a teammate - I don't have to ask someone what users means, but I do have to ask what data means. While I don't often find the best names, I try to optimize my code for the reader by following some basic rules.

The Rules:

Use Meaningful Prefixes

While these prefixes aren't universal, they are great to establish a shared language within your team. Using them consistently throughout your codebase can make reading comprehension easier.

  • get, find, fetch for functions that return a value or a Promise that resolves to a value without mutating arguments or itself.
  • set, update for functions that mutate arguments or the callee for member functions. These functions may also return the updated value or a Promise that resolves to the updated value.
  • on, handle for event handler functions. My team's convention is that onEvent is passed through props into the component and handleEvent is declared inside the component.
  • is, should, can for boolean variables and functions with boolean return values.

Any convention that becomes a standard in your team can help with readability. Make sure to document these in the project README or wiki. Creating custom linters to enforce these would be even more effective.

Use Words that Add Meaning

As an example, developers often name variables data by default, but let's examine a couple of its definitions:

  • "factual information (such as measurements or statistics) used as a basis for reasoning, discussion, or calculation"
  • "information in digital form that can be transmitted or processed"

These definitions could refer to any variable we process, so they give the reader no information. Let's look at an example that doesn't follow this rule:

function total(data) {
  let total = 0;
  for (let i = 0; i < data.length; i++) {
    total += data[i].value;
  }

  return total;
}
Enter fullscreen mode Exit fullscreen mode

We know this function calculates a total of something, but we're not sure what.

Exceptions

Sometimes your variable could actually contain anything, like a network request response body. Libraries like axios use data, which is a reasonable name in this context. Even in this scenario, the alternative body conveys more meaning and is what the native web API fetch uses in its Response.

Use Full Words

Like everyone else's, the System 1 part of my brain always tells me to take shortcuts to finish my task sooner. When it comes to variable naming, shortcuts often mean abbreviations or single character variable names.

Like before, let's look at a function that doesn't follow the rule:

function totBal(accts) {
  let tot = 0;
  for (let i = 0; i < accts.length; i++) {
    tot += accts[i].bal;
  }

  return tot;
}
Enter fullscreen mode Exit fullscreen mode

We can do some mental gymnastics to guess that accts means accounts and tot is total, but we can't process the code at a glance.

Exceptions

Common industry abbreviations are preferred over their long form (e.g. URL, API, CSS).

Don't Use "Fluff" Words

Container and Wrapper only have meaning in relation to the thing they're containing. The problem is that any component that isn't a base element contains another component. You also end up in the awkward position of naming components MyComponentContainerContainer. The same applies to Wrapper.

Exceptions

In some contexts, these "fluff" words can have significant meaning. A common pattern in React class components is the presentation/container component pattern. Container in this case may indicate a component that manages state on behalf of a presentation component - just make sure you consistently use it for this purpose, or it loses meaning.

Spelling Matters

Misspelling words creates bugs and makes searching your code harder. Typos are easy to ignore, but having the right spelling for everything in your codebase makes a world of difference, especially when attempting global find/replace.

Putting it Together

Applying all the rules at once, we get the following function:

function getAccountsTotalBalance(accounts) {
  let totalBalance = 0;
  for (let accountIndex = 0; accountIndex < accounts.length; accountIndex++) {
    totalBalance += accounts[accountIndex].balance;
  }

  return totalBalance;
}
Enter fullscreen mode Exit fullscreen mode

While accountIndex vs. i might be contentious, the rest of the function should be much clearer. getAccountsTotalBalance fully communicates the intent of the function and the prefix get indicates that it will not result in any mutations. It's worth the code author investing increased effort in exchange for the benefit of the reader. Your future self will appreciate the extra work when they're maintaining the code six months later.

If you're worried about line length, consider using a tool like Prettier to automatically format the code.

Conclusion

The goal of these rules is to bring as much meaning as possible to the code we write for future readers. Find the ones that work for your context, and if a rule is doing more harm than good, change or abandon it. Codifying your team's rules will help communicate your thoughts on the subject and is not meant to bring a hammer down on your teammates.

Please share any other rules you follow when naming variables, functions, classes, etc. or let me know if you disagree with any of the rules here and how you'd change them.

Latest comments (54)

Collapse
 
mrdulin profile image
official_dulin • Edited

If undefined is a meaningful value, replace it with a variable. E.g. We will do something if scoreType is all.

Bad

if (scoreType === undefined) {
  // do something
} 
Enter fullscreen mode Exit fullscreen mode

Good:

const all = undefined;
if(scoreType === all) {
  // do something
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
skylee91 profile image
Sky Lee

Yes stop using data, details, info, list as variable as name too. Name it with specify name.

Collapse
 
ricardo profile image
Ricardo Luz

Hey Devin, thanks for sharing your thoughts in this outstanding article! You commented about use lint to enforce some name patterns. However, I never heard about some linter that does that, do you know someone? Otherwise, it's a great idea to a new open source project! I am already using a vscode plugin to typo check, and it's helping me to avoid this kind of errors once English isn't my mother tongue, as well as find errors left by other devs and fix it.

Collapse
 
dcwither profile image
Devin Witherspoon

I’m not sure if there’s any open source project doing this or if it’s even feasible to do in a generic manner. Some things like checking for returning a promise/async function to avoid get would be easy enough.

Taking advantage of team conventions, you could enforce that there is a prefix on functions, and that some prefixes are applied correctly - though there’s a limit to how much you can do here(e.g. you could enforce that if it returns a Boolean literal it must begin with is, can, or should, but that doesn’t cover all cases).

Because this kind of linter would benefit from knowing team conventions, I don’t think it would be very effective as an open source project.

Collapse
 
joaozitopolo profile image
Joao Polo

Let me put my 10 cents... the prefix "eval" is useful for evaluate something.
For example, evalAccountsTotalBalance(...) means I'll do some direct operation with arguments.

 
dcwither profile image
Devin Witherspoon

Nice, I would have thought the joke was older!

Collapse
 
dcwither profile image
Devin Witherspoon

Not sure if you’re joking, but that wasn’t part of the original quote, it was a joke that was later added. I’m not sure who said that part first though, might not be as well documented.

Collapse
 
vishnuharidas profile image
Vishnu Haridas • Edited

Giving meaningful names are important. Suddenly a few incidents popped up in my mind.

Once I was going through a legacy code, which had a variable like this: bool isWasStarted. I still don't know what it was used for!

The same project was having a function writeLog(text), and I expected the function to write the text to the output stream. The function body looks like this:

function writeLog(text){
   UserManager.createUser(text);
}
Enter fullscreen mode Exit fullscreen mode

Seriously, why people do this?!

Collapse
 
phongduong profile image
Phong Duong

My native language is not English. I sometimes can't find a name for the variable or function. This makes me confused when I read my code later. So I reduce using the variable and try to use the function chaining. Thank you for sharing.

Collapse
 
josefjelinek profile image
Josef Jelinek

accountIndex is hard to read because the reader really needs to read it... for i there is instant recognition in the brain.

  for (let accountIndex = 0; accountIndex < accounts.length; accountIndex++) {
    totalBalance += accounts[accountIndex].balance;
  }
Enter fullscreen mode Exit fullscreen mode

vs.

  for (let i = 0; i < accounts.length; i++) {
    totalBalance += accounts[i].balance;
  }
Enter fullscreen mode Exit fullscreen mode

fortunatelly, there is a superior alternative (without going into Array methods):

  for (const account of accounts) {
    totalBalance += account.balance;
  }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
drumstix42 profile image
Mark

Yeah i think it's important to use words where it makes sense, but sometimes the syntax gets lost in long lines because of longer words. For variables, meaningful names are important, but I agree in things like loops, it's better to use alternative methods or function methods instead! +1 for "for...of"

Some comments may only be visible to logged-in visitors. Sign in to view all comments.