A name is the smallest unit of documentation in a program. Before anyone reads a function body, they read its name. Before they open a file, they read the variable names inside it. And a name that is vague, inconsistent, or misleading costs every future reader time — sometimes a lot of it.
JavaScript does not enforce naming conventions the way it enforces syntax. You can call a
variable x, data, or temp2 and the language will not
object. That freedom is exactly why conventions matter: with no enforcement, consistency is
the only thing standing between a readable codebase and a maze.
This guide covers the whole subject: the difference between language rules and style conventions, the four casing styles, what to name each kind of value, the prefix patterns that make code self-documenting, the mistakes that make names actively misleading, and how to enforce a convention across a team.
is or has, and name things by what they mean rather than what
they hold.
Rules vs Conventions
Two different things get called “naming rules,” and separating them makes everything else clearer.
Enforced by the parser
A name cannot start with a digit.
A name cannot contain hyphens or spaces.
A name cannot be a reserved word.
Break one of these and the script does not run at all.
Agreed by people
Variables use camelCase.
Classes use PascalCase.
Booleans start with is.
Break one of these and nothing happens — except that someone later has to read it.
The rules are covered in detail in JavaScript Case Sensitivity. This guide is about the second column — the choices that make a codebase readable.
There is no universally correct convention. There is only a convention that a team applies consistently. The worst outcome is not choosing an unusual style — it is having three styles in one file.
Why conventions are worth the effort
Searchability
A consistent name is findable. Searching for fetchUser works when everything follows the same pattern.
Predictability
After a week in a codebase, you can guess names before you read them. That is the goal.
Fewer typos
Consistent casing means fewer mismatched names, and a typo is easier to spot.
Self-documenting code
A good name removes the need for a comment. isExpired explains itself.
Easier review
Reviewers can focus on logic instead of deciphering what a name is supposed to mean.
Faster onboarding
A new developer finds things by pattern rather than by reading everything.
The Four Casing Styles
JavaScript has four conventional casing styles, and each one is tied to a specific kind of thing. Learning the mapping is most of the battle.
Starts lowercase, capitalizes each following word.
Used for variables, functions, and object methods.
Capitalizes every word including the first.
Used for classes, constructors, and React components.
All uppercase with underscores between words.
Used for true constants — values fixed before the program runs.
A leading underscore signals “internal — do not use from outside”.
Used for internal helpers and legacy “private” members.
What about kebab-case?
kebab-case is a valid and common convention — in CSS, in HTML class names, and
in file names. In JavaScript it is a syntax error, because the hyphen is the subtraction
operator.
const user-name = 'Ada';
// Parsed as: const user - name = 'Ada';
// SyntaxError: Unexpected token '-'
// Valid in CSS and HTML, not in JS.The full mapping
| Kind of thing | Style | Example |
|---|---|---|
| Variables | camelCase | userName, totalPrice |
| Functions | camelCase | calculateTotal, fetchUser |
| Object methods | camelCase | user.getName() |
| Classes | PascalCase | UserAccount, ShoppingCart |
| Constructor functions | PascalCase | function Person(name) |
| React components | PascalCase | <UserCard /> |
| True constants | SCREAMING_SNAKE_CASE | MAX_RETRIES, API_URL |
| Internal helpers | _leadingUnderscore | _cache, _internalHelper |
| Private class fields | #hash prefix | this.#count |
| Module names | camelCase or kebab-case | userService.js, utils.js |
| CSS classes | kebab-case | .user-card |
What to Name Each Kind of Value
Variables — a noun
A variable holds a value, so its name should be a noun that describes what the value means, not what it is.
const data = getUser();
const str = user.name;
const arr = user.posts;
const temp = user.age;
const x = user.email;
const obj = { a: 1, b: 2 };
// Every one of these names tells
// you nothing about the value.const currentUser = getUser();
const userName = user.name;
const userPosts = user.posts;
const userAge = user.age;
const userEmail = user.email;
const options = { a: 1, b: 2 };
// Each name describes what the value
// represents.Functions — a verb
A function does something, so its name should be a verb phrase. Reading it at the call site should describe the action.
// A verb phrase describes what the function does
function calculateTotal(items) { }
function fetchUser(id) { }
function renderCard(data) { }
function validateEmail(value) { }
function formatPrice(cents) { }
function parseQueryString(search) { }
function isWithinRange(value, min, max) { }
// Nouns as function names are a smell —
// they usually mean the function is doing
// too much or the name is not specific
function user(id) { } // what about the user?
function total(items) { } // total what?
Classes — a noun in PascalCase
// A class describes a kind of thing
class UserAccount { }
class ShoppingCart { }
class HttpClient { }
class ValidationError extends Error { }
// Methods inside a class still use camelCase
class UserAccount {
constructor(name) {
this.name = name;
this.#createdAt = new Date();
}
#createdAt; // private field
getDisplayName() { }
updateEmail(newEmail) { }
isActive() { }
}
Constants — SCREAMING_SNAKE_CASE, but only when it is true
This is the rule people get wrong most often. SCREAMING_SNAKE_CASE is reserved for values
that are known before the program runs — configuration, limits, magic numbers. A
const holding a computed value is not one of those.
function process(data) {
const RESULT = data.map(transform);
const COUNT = data.length;
const AVERAGE = SUM / COUNT;
// These are const, but they are
// computed at runtime. SCREAMING
// case is misleading.
}function process(data) {
const result = data.map(transform);
const count = data.length;
const average = sum / count;
// Same `const` keyword, but
// camelCase because the value
// is computed, not fixed.
}// True constants — SCREAMING_SNAKE_CASE
const MAX_RETRIES = 3;
const API_BASE_URL = 'https://api.example.com';
const DEFAULT_TIMEOUT_MS = 5000;
const TAX_RATE = 0.2;
const SUPPORTED_LOCALES = ['en', 'fr', 'de'];
// Module-level config objects often get this treatment too
const CONFIG = Object.freeze({
retries: 3,
timeout: 5000
});
// But a value computed from other values is camelCase,
// even at module level
const defaultTimeout = MAX_RETRIES * 1000; // computed
Ask: “could this value ever be different at runtime?” If yes, it is not a true constant — use camelCase. If it is fixed forever, use SCREAMING_SNAKE_CASE.
The Prefix Patterns That Do the Heavy Lifting
A small set of prefixes carries a surprising amount of meaning. Learning them makes names self-documenting without any extra effort.
-
Booleans that describe state.
isReady,hasPermission,isLoading,hasError. The name reads as a question, which is exactly what anifstatement asks. -
Booleans that describe capability or intent.
canEdit,shouldRetry,canSubmit. Useful when the boolean is about what is allowed rather than what currently is. -
Event handlers and callbacks.
handleClickis the function that does the work;onClickis the prop or option it is passed to. The distinction makes the role obvious. -
Accessors.
getUser()reads a value;setUser()writes one. In classes,getandsetare also real keywords for property accessors. -
Data retrieval.
fetchUser()suggests a network request;loadConfig()suggests reading from disk or cache. The verb signals the cost.
Booleans should read as a question
// These read naturally inside an if statement
if (isLoading) { }
if (hasPermission) { }
if (canEdit) { }
if (shouldRetry) { }
// These do not — the reader has to work out
// what the boolean means
if (loading) { }
if (permission) { }
if (edit) { }
if (retry) { }
// And avoid negative names — a double negative is
// almost always harder to read
if (!isNotReady) { } // confusing
if (isReady) { } // clearer
// If the value is genuinely the absence of something,
// name it that way and use it that way
if (isMissing) { } // fine — it reads as a question
Handlers vs callbacks
function click() { }
button.addEventListener('click', click);
// `click` collides with the event name
// and reads like a noun.function handleClick(event) { }
button.addEventListener('click', handleClick);
// Or, in a component API:
<Button onClick={handleClick} />
// handle = the function
// on = the prop it is passed toSee the difference in real code
This example is built entirely with prefix conventions. Read the variable names and it should be clear what each one holds before you look at the code that produces it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Prefix Conventions</title>
<style>
body {
font-family: system-ui, sans-serif;
padding: 28px;
background: #f8fafc;
margin: 0;
color: #0f172a;
}
.panel {
background: #fff;
border: 1px solid #e2e8f0;
border-radius: 14px;
padding: 22px;
max-width: 420px;
}
.status {
display: flex;
align-items: center;
gap: 8px;
font-size: 0.82rem;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
margin-bottom: 14px;
}
.dot {
width: 8px;
height: 8px;
border-radius: 50%;
}
.dot--on { background: #16a34a; box-shadow: 0 0 8px rgba(22,163,74,.5); }
.dot--off { background: #cbd5e1; }
.label { color: #64748b; }
.btn {
border: 0;
border-radius: 10px;
background: #0891b2;
color: #fff;
font: inherit;
font-weight: 600;
font-size: 0.88rem;
padding: 10px 18px;
cursor: pointer;
margin-right: 8px;
}
.btn:hover { background: #0e7490; }
.btn:disabled { background: #cbd5e1; cursor: not-allowed; }
</style>
</head>
<body>
<div class="panel">
<div class="status">
<span class="dot dot--off" id="dot"></span>
<span id="label">Not running</span>
</div>
<button class="btn" id="toggle">Start</button>
</div>
<script>
// Every name below signals its role through its prefix
let isRunning = false; // boolean — reads as a question
let hasStartedOnce = false; // boolean — also a question
const MAX_TOGGLES = 5; // true constant
let toggleCount = 0; // computed value — camelCase
const dotElement = document.getElementById('dot');
const labelElement = document.getElementById('label');
const toggleButton = document.getElementById('toggle');
function canToggle() { // capability — can
return toggleCount < MAX_TOGGLES;
}
function renderStatus() { // verb — does something
dotElement.className = isRunning ? 'dot dot--on' : 'dot dot--off';
labelElement.textContent = isRunning ? 'Running' : 'Not running';
toggleButton.textContent = isRunning ? 'Stop' : 'Start';
toggleButton.disabled = !canToggle();
}
function handleToggle() { // handler — handle
if (!canToggle()) return;
isRunning = !isRunning;
hasStartedOnce = true;
toggleCount += 1;
renderStatus();
}
toggleButton.addEventListener('click', handleToggle);
renderStatus();
</script>
</body>
</html>
Notice how the names alone tell you the shape of the program.
isRunning and hasStartedOnce are obviously booleans.
canToggle() is obviously a capability check. handleToggle is
obviously an event handler. Nothing here needs a comment to explain what it holds.
How Long Should a Name Be?
The right length depends on the scope. A name used across a whole module needs to carry its meaning on its own. A name used inside a two-line loop can afford to be short.
// Fine — the scope is two lines and the meaning is obvious
for (let i = 0; i < items.length; i++) { }
// Fine — conventional mathematical shorthand
function distance(x1, y1, x2, y2) { }
// Not fine — `u` is used across a whole module
export function u(id) { } // what is u?
// Better
export function fetchUser(id) { }
// Fine — a short name inside a small callback
items.map(n => n * 2);
// Not fine — a short name for something important
const d = new Date();
const t = calculateTotal(cart); // what is t?
// Better
const createdAt = new Date();
const orderTotal = calculateTotal(cart);
The length of a name should be proportional to the size of its scope. A loop index can be one character; a variable that lives in a module for its whole life should be spelled out completely.
When short names are acceptable
- Loop indices.
i,j, andkare universal. - Coordinates and dimensions.
x,y,w,hin geometry or graphics code. - Array callbacks.
n,item,elinside amaporforEach. - Error catch variables.
erroreis universally understood. - Event variables.
eventorevtinside a handler.
Everywhere else, a short name costs more time to decode than it saved in typing.
Abbreviations: usually a mistake
Shorter to type, much harder to read.
Twice as long, read instantly.
Only the author knows what this does.
Self-explanatory at every call site.
Vowel removal is not compression.
Long, and worth every character.
The argument for short names was always typing speed. That argument stopped being true around 2010. Type three characters and press Tab — the cost is the same, and the reader gets a real name.
Naming in Practice: Before and After
The clearest way to see the value of conventions is a refactor. Here is the same component written twice. Both versions work; only one is maintainable.
Before — vague and inconsistent
// What is `d`? What is `x`? What does `f` do?
function f(d) {
const x = d.list;
const t = x.length;
if (t === 0) {
return 'no data';
}
let s = 0;
for (let i = 0; i < t; i++) {
s += x[i].p;
}
return s;
}
const d = getData();
const r = f(d);
console.log(r);
// Inconsistent casing in the same file
const user_name = 'Ada';
const UserEmail = 'ada@example.com';
const MAX_ITEM_COUNT = 10;
const default_count = 5;
After — descriptive and consistent
// Every name says what it holds
function calculateOrderTotal(order) {
const lineItems = order.lineItems;
const itemCount = lineItems.length;
if (itemCount === 0) {
return 0;
}
let total = 0;
for (let i = 0; i < itemCount; i++) {
total += lineItems[i].price;
}
return total;
}
const currentOrder = fetchOrder();
const orderTotal = calculateOrderTotal(currentOrder);
console.log(orderTotal);
// Consistent casing throughout
const userName = 'Ada';
const userEmail = 'ada@example.com';
const MAX_ITEM_COUNT = 10; // true constant
const defaultItemCount = 5; // computed value
| Before | After | Why |
|---|---|---|
f |
calculateOrderTotal |
The function name describes the action |
d |
order |
The parameter name describes the value |
x |
lineItems |
Reads as a noun in the code below it |
t |
itemCount |
The count has a real name |
s |
total |
The accumulator is self-describing |
'no data' |
0 |
Returning a number consistently is better than a string sentinel |
user_name |
userName |
One casing style instead of three |
default_count |
defaultItemCount |
Not a true constant, so camelCase |
Common Naming Mistakes
Each of these makes a name actively harder to work with. They are the ones that come up most often in real code reviews.
1. Single letters outside a tiny scope
function p(u) {
const r = u.n + ' ' + u.l;
const e = u.m.toLowerCase();
return { r, e };
}
// What is p? What is u? What is r?
// The reader has to open the
// implementation to find out.function formatUserProfile(user) {
const displayName = user.firstName + ' ' + user.lastName;
const normalizedEmail = user.email.toLowerCase();
return { displayName, normalizedEmail };
}2. Names that repeat the type
const strName = 'Ada';
const arrItems = [1, 2, 3];
const objConfig = { a: 1 };
const numCount = 5;
const boolIsReady = true;
// The type is already visible in
// the value. The prefix adds nothing.const userName = 'Ada';
const lineItems = [1, 2, 3];
const config = { a: 1 };
const itemCount = 5;
const isReady = true;
// `userName` conveys "string"
// through meaning, not a prefix.3. Catch-all names: data, info, temp
function process(data) {
const info = data.info;
const temp = info.value;
const result = temp * 2;
return result;
}
// Every name here is a placeholder.function doubleDiscount(product) {
const discountInfo = product.discount;
const discountPercent = discountInfo.value;
const doubledDiscount = discountPercent * 2;
return doubledDiscount;
}4. Negative boolean names
const isNotReady = true;
if (!isNotReady) {
// "if not not ready" — the reader
// has to work out what this means
}
const dontShow = false;
if (!dontShow) { }const isReady = false;
if (isReady) {
// reads naturally
}
const shouldShow = true;
if (shouldShow) { }5. Inconsistent casing in the same file
const user_name = 'Ada';
const userEmail = 'x@y.com';
const UserAge = 36;
const USER_CITY = 'London';
const user-country = 'UK';
// Which convention is this file
// following? None of them.const userName = 'Ada';
const userEmail = 'x@y.com';
const userAge = 36;
const userCity = 'London';
const userCountry = 'UK';6. Names that lie
// Returns an array, named as a boolean
function isValid() {
return [true, false, true];
}
// Named as a count, holds a string
const itemCount = 'many';
// Named as a getter, mutates state
function getUser() {
currentUser = fetchUser();
return currentUser;
}function getValidationResults() {
return [true, false, true];
}
const itemCountLabel = 'many';
function loadUser() {
currentUser = fetchUser();
return currentUser;
}7. Names that differ by one character
const userList = [];
const usersList = [];
const listOfUsers = [];
// Three names for what is probably
// the same thing, or three things
// nobody can distinguish.const activeUsers = [];
const archivedUsers = [];
const invitedUsers = [];
// The name says which set of users
// this is, not just that it is a list.8. Abbreviating past the point of clarity
function calcTtl(itms) {
const sbttl = itms.reduce((s, i) => s + i.p, 0);
const tx = sbttl * 0.2;
return { sbttl, tx };
}function calculateTotal(items) {
const subtotal = items.reduce((sum, item) => sum + item.price, 0);
const tax = subtotal * 0.2;
return { subtotal, tax };
}9. Shadowing a built-in
function process(list) {
const Array = list.slice();
// `Array` now refers to a local
// variable. Any later use of the
// built-in Array inside this
// function breaks.
}function process(list) {
const items = list.slice();
// No collision with the built-in.
}10. Naming by position rather than role
const leftColumn = getSidebar();
const rightColumn = getMainContent();
const topBar = getHeader();
// On a phone, the sidebar often
// moves above the content. Now the
// names are factually wrong.const sidebar = getSidebar();
const mainContent = getMainContent();
const siteHeader = getHeader();
// Where it sits can change.
// What it is does not.
A name like data makes you read the code. A name like
itemCount that actually holds a string makes you trust something false. When
you change what a value holds, rename it.
Making It Stick: Tooling and Consistency
A convention that lives only in a document drifts. A convention enforced by a tool holds. The good news is that the tooling is easy to set up.
ESLint
// .eslintrc.json — enforce the common conventions
{
"rules": {
// Variables and functions must be camelCase
"camelcase": ["error", { "properties": "always" }],
// No shadowing built-ins or outer variables
"no-shadow": "error",
"no-shadow-restricted-names": "error",
// No redeclaring — catches accidental duplicates
"no-redeclare": "error",
// Custom pattern rules for specific naming families
"id-match": ["error", "^[a-z][a-zA-Z0-9]*$", {
"properties": false,
"onlyDeclarations": true
}]
}
}
TypeScript’s naming-convention rule
If you use TypeScript with the ESLint plugin, the
@typescript-eslint/naming-convention rule lets you express the whole table in
one place.
// eslint.config.js — the full convention as a rule
'@typescript-eslint/naming-convention': [
'error',
// Variables — camelCase, or SCREAMING_SNAKE_CASE for constants
{
selector: 'variable',
format: ['camelCase', 'UPPER_CASE']
},
// Booleans must start with a recognised prefix
{
selector: 'variable',
types: ['boolean'],
format: ['camelCase'],
prefix: ['is', 'has', 'can', 'should', 'did']
},
// Functions — camelCase
{
selector: 'function',
format: ['camelCase']
},
// Classes, interfaces, and type aliases — PascalCase
{
selector: 'typeLike',
format: ['PascalCase']
},
// Object properties may also be snake_case, for API payloads
{
selector: 'objectLiteralProperty',
format: ['camelCase', 'snake_case']
}
]
Prettier does not do this — and that is fine
Prettier formats whitespace, quotes, and line breaks. It does not rename anything, and it cannot enforce a casing convention. That is what ESLint is for. The two work together: Prettier handles layout, ESLint handles rules.
| Concern | Prettier | ESLint |
|---|---|---|
| Indentation and line length | Yes | No |
| Quote style | Yes | Partly |
| Semicolons | Yes | Partly |
| Naming conventions | No | Yes |
| Unused variables | No | Yes |
| Shadowed variables | No | Yes |
| Possible bugs | No | Yes |
A linter that only runs when someone remembers is a linter that does not run. Add
eslint . to the CI pipeline so a naming violation blocks the build rather
than appearing in a review comment.
Best Practices
These habits cover nearly every naming decision you will face. When in doubt, start here.
camelCase for variables and functions
The default for everything that is not a class or a true constant.
PascalCase for classes
Classes, constructors, and React components all start with a capital letter.
SCREAMING_SNAKE_CASE for true constants
Only for values fixed before the program runs. Computed values use camelCase.
Prefix booleans
is, has, can, should — they read as a question.
Verbs for functions, nouns for variables
fetchUser does something; currentUser holds something.
Match length to scope
Short names in tiny scopes, fully spelled out everywhere else.
Avoid abbreviations
Autocomplete makes long names cost nothing. Use the readable version.
Name by role, not position
sidebar, not leftColumn. Layouts change; roles do not.
Enforce it with a linter
A convention that is checked in CI is a convention that survives.
Say what a thing means, match the length to the scope, use the right casing for the right kind of value, and let ESLint keep everyone honest.
Frequently Asked Questions
1. What are JavaScript naming conventions?
Naming conventions are agreed-upon rules for choosing and formatting names in code. They cover which casing style to use for each kind of value, how long a name should be, and which prefix patterns signal a boolean, a handler, or an internal value. They are not enforced by the language itself.
2. What casing style should I use in JavaScript?
camelCase for variables and functions, PascalCase for classes and constructors, SCREAMING_SNAKE_CASE for true constants, and a leading underscore for anything internal. Hyphens are not valid in JavaScript identifiers because they mean subtraction.
3. Why do JavaScript naming conventions matter?
Code is read far more often than it is written. Consistent names make a codebase searchable, reduce the chance of typo bugs, and let any developer predict what a function or variable does before reading its implementation.
4. Are naming conventions the same as the language rules?
No. The language rules determine whether a name is legal and are enforced by the parser — a name cannot start with a digit or be a reserved word. Naming conventions are a style choice and are not enforced by the language, though a linter can enforce them.
5. How long should a variable name be?
Long enough to be unambiguous and short enough to read. Two or three words usually
covers it. The length should be proportional to the scope: a loop counter inside a
two-line loop can be i, but a value used across a whole module needs a
descriptive name.
6. Should I use short names like a, b, or x?
Only in very small scopes where the meaning is obvious — a loop index, or a mathematical coordinate. In any other context a short name costs more time to decode than it saves in typing, and it becomes a genuine problem when the code is read later.
7. How should I name boolean variables?
Prefix booleans so they read as a question: isReady,
hasPermission, canEdit, shouldRetry. This makes
the condition in an if statement read naturally, and it prevents the
common mistake of writing a negative boolean name such as isNotReady.
8. How should I name event handlers?
The usual convention is a handle prefix for the function that does the
work, such as handleClick or handleSubmit, and an
on prefix for the prop or callback it is passed to, such as
onClick. This makes the difference between a handler and a callback
obvious.
9. Should I include the type in a variable name?
No. A name like strName or arrItems is called Hungarian
notation and it duplicates information the value already carries. If the type matters,
a name like userName or lineItems conveys it through meaning
instead, and TypeScript can enforce it properly.
10. How do I name a constant?
Use SCREAMING_SNAKE_CASE only for values known before the program runs —
configuration, limits, and magic numbers, such as MAX_RETRIES or
API_BASE_URL. A const declared inside a function that holds a
computed value is not a true constant and should use camelCase.
11. What does a leading underscore mean in JavaScript?
It is a convention signalling that a name is internal and should not be used from outside. It is not enforced by the language. For genuinely private class members, use the hash prefix, which the language does enforce.
12. Can a linter enforce naming conventions?
Yes. ESLint includes rules such as camelcase and id-match,
and @typescript-eslint/naming-convention for TypeScript. A linter turns a
convention from a suggestion into a check, which is the most reliable way to keep a
codebase consistent across contributors.
Key Takeaways
- Naming conventions are style, not syntax — the language does not enforce them.
- camelCase for variables and functions, PascalCase for classes, SCREAMING_SNAKE_CASE for true constants.
- Hyphens are not valid in JavaScript identifiers — use camelCase instead.
- Prefix booleans with
is,has,can, orshould. - Use verbs for functions and nouns for variables.
- Match the length of a name to the size of its scope.
- Use
handlefor the handler function andonfor the prop it is passed to. - Avoid Hungarian notation — the type is already in the value.
- Avoid catch-all names like
data,info, andtemp. - A name that lies is worse than a name that is vague — rename when the value changes.
- Name by role, not by position — layouts change, roles do not.
- Enforce the convention with ESLint in CI so it survives past the first week.
What to Learn Next
Now that the naming conventions are clear, the next step is the language rules that sit underneath them. Read JavaScript Case Sensitivity for what the parser actually enforces, and JavaScript Strict Mode for the mode that catches several naming mistakes automatically.
From there, explore JavaScript Syntax Explained, JavaScript Statements and Expressions, and JavaScript Functions Explained. For the CSS side of the same subject, read CSS Naming Conventions.
If you are still connecting the pieces, read What Is JavaScript?, JavaScript Comments, and JavaScript vs TypeScript for the surrounding context.
Practice Challenge
The fastest way to internalize a convention is to apply it to code that was written badly. This exercise takes about twenty-five minutes.
- Create
index.htmlandapp.js, and load the script with<script src="app.js" defer></script>. - Write a deliberately badly named function: short name, single-letter parameters, and a body full of
data,temp, andx. Confirm it works. - Add a second function that returns a boolean but is named as a noun, such as
status(). - Add four variables in the same file using four different casing styles:
user_name,userEmail,UserAge, andUSER_CITY. - Add a
constinside a function that holds a computed value and name it in SCREAMING_SNAKE_CASE. - Now refactor every name: rename the function to a verb phrase, its parameters to descriptive nouns, and the internal variables to meaningful names.
- Rename the boolean function to start with
is,has, orcan. - Convert all four variables to camelCase, and change the computed constant to camelCase as well.
- Add a genuine constant at the top of the file with SCREAMING_SNAKE_CASE — something like
MAX_ITEMS. - Add an event listener and name the handler with a
handleprefix. - Now install ESLint in the project and enable the
camelcase,no-shadow, andno-redeclarerules. Run it and see whether your refactored file passes. - Finally, deliberately rename one variable to differ from its use site by a single capital letter. Run ESLint and confirm it catches the undeclared reference.
If you complete those steps, you have written code that violates every major convention, refactored it into something readable, added a genuine constant alongside a computed one, and configured a linter to keep the rules in place. That sequence — write badly, refactor, enforce — is the whole practice of naming conventions. The refactor is the part that teaches you what the rules are for.