Coding style & naming
Learn JavaScript naming, formatting, comments, and clear-code habits that make programs easier to read, debug, and share.
- 01Pick clear namesName variables and functions so the name says what each one is for.
- 02Let a formatter handle layoutExplain what Prettier changes in your code, and why teams use it.
- 03Choose clear over cleverWrite comments and if statements that help the next person who reads your code.
Code that people can read
JavaScript does not care what you call a variable. A variable named x and a variable named minimumPrice work the same way. If the code follows JavaScript's rules, it runs.
People are different. We read the names, the spacing, and the comments to work out what a program does.
Coding style means the choices you make so that code is easy for people to read. It covers four things:
- the names you give to variables and functions,
- the layout: spaces, indents, and line breaks,
- the comments you write,
- whether you write each decision in a plain way or a tricky way.
Good style makes code easier to read, to fix, and to change later. This lesson uses only beginner JavaScript: const, let, functions, arrays, strings, numbers, true/false values, and a few if statements. The full rules for making variables come later, in the Variables lesson.
Good style lets a reader answer four questions fast: What is this value? What does this function do? Which lines belong together? Why is this unusual line here?
Imagine you are moving to a new home. A box labeled “Kitchen: plates” goes straight to the kitchen. A box labeled “stuff” has to be opened before anyone knows where it goes. A clear label tells every helper what is inside.
- In real life: A box labeled “Kitchen: plates”
- In JavaScript: A variable named
orderItems - In real life: A box labeled “stuff”
- In JavaScript: A variable named
dataorarr2 - In real life: Helpers carry each box to the right room without opening it
- In JavaScript: Readers know what each value is without reading every line
You already met comments and spaces in Statements, comments & semicolons, strict mode in Strict mode, and your editor in Setting up your tools. This lesson puts those basics together to make code easy to read.
Naming variables & functions
INTERACTIVEA good name says what a value is for: the job it does in the program. price is better than n. If the price is the lowest price allowed, minimumPrice is even better. A name does not need to be long. It needs to say enough for someone reading the code around it.
JavaScript programmers usually write names in the styles below. Read each row as: for this kind of thing, write the name this way.
| What you are naming | How to write the name | Examples |
|---|---|---|
| Variables and functions | camelCase: the first word is lowercase, and each later word starts with a capital letter. | orderItems, calculateTotal, formatDate |
| Classes and components (you'll meet them later) | PascalCase: every word starts with a capital letter. | ArticleSorter, ShoppingCart |
| Fixed settings that never change | UPPER_SNAKE_CASE: all capital letters, with _ between the words. | MAX_RETRY_ATTEMPTS, API_TIMEOUT_MS |
| True/false values | Start with a yes/no word such as is, has, can, or should. | isMenuOpen, hasCoupon, canRetry, shouldShowWarning |
| Lists of things | Use a plural word. | users, messages, searchResults |
Function names usually start with a verb, an action word, because a function does a job: getUser, calculateTotal, renderMenu. Avoid short forms unless everyone on your team already uses them. Avoid numbers that mean nothing, like arr2. A reader should never have to guess.
const orderItems = ["tea", "notebook"];
const hasCoupon = true;
console.log(orderItems.length);
console.log(hasCoupon);Line 1 makes an array, which is a list. The plural name orderItems tells you it holds more than one item. Line 2 stores true. The name hasCoupon reads like a question: does the order have a coupon? Line 4 prints 2 and line 5 prints true. The values are simple, and the names tell you what they mean before you look at them.
arr2 makes you look inside to find out what it holds. orderItems tells you before you look.const cartTotal = 24;
const minimumFreeShippingTotal = 30;
const needsShippingFee = cartTotal < minimumFreeShippingTotal;
console.log(needsShippingFee);Lines 1 and 2 name two numbers: the cart total, and the smallest total that ships for free. Line 3 compares them and stores the answer, true or false. Its name, needsShippingFee, says what that answer means. 24 is less than 30, so line 5 prints true. Later, if (needsShippingFee) reads almost like a sentence.
In the playground below, the function works, but its names are vague. Press a button to swap one vague name for a clear one.
function doIt(arr2, x, flag) { let d = 0; for (const item of arr2) { if (item.price >= x) { d = d + item.price; } } if (flag) { d = d - 5; } return d;}doIt(...)42calculateEligibleTotal(...)42- The list name is plural and specific.
- The true/false name starts with a yes/no word.
- The function name starts with a verb.
- No names look temporary any more.
You have changed 0 of 5 names. For each one, ask: what job does this value do?
The result did not change. That is what a safe rename means. The function still adds up the items that cost at least the minimum price, then takes 5 off when there is a coupon. The new version is just easier to read.
const userName = "Asha";
const MAX_RETRY_ATTEMPTS = 3;
console.log(userName);
console.log(MAX_RETRY_ATTEMPTS);Both lines use const, so this program never gives either name a new value. Only the retry limit is written in capitals. It is a fixed rule for the whole app, like a setting. Line 4 prints Asha and line 5 prints 3. An ordinary value like userName stays in camelCase.
ArticleSorterarr2isMenuOpendoStuffcalculateTotaldataMAX_RETRY_ATTEMPTStmp
Sort each name: does it tell you what the value is for? If you guess wrong, the card explains what clue was missing.
Formatting with Prettier
COMPAREFormatting is the layout of code: indents, line breaks, spaces, quotes, semicolons, and commas at the end of lists. Messy layout can make working code look broken, because you cannot see which lines belong together.
A newspaper uses the same column layout on every page. Readers stop noticing the layout and just read the story. Nobody argues about the width of each column, because the rule was set once.
- In real life: Every page uses the same columns
- In JavaScript: Every file uses the same indents and line breaks
- In real life: Readers focus on the story
- In JavaScript: Programmers focus on what the code does, not on the spaces
- In real life: The editors choose the layout rules once
- In JavaScript: The team chooses the formatter's rules once
Prettier is a popular formatter: a tool that rewrites the layout of your code for you. In a real project you install it, and your editor runs it. This page does not run Prettier. It shows a before-and-after pair that was written ahead of time. The "after" code is laid out the way Prettier lays it out with its default settings.
const profile={name:"Mina",roles:["mentor","reviewer"]};function greet(name){return "Hello, "+name+"!"}console.log(greet(profile.name));const profile = { name: "Mina", roles: ["mentor", "reviewer"],}; function greet(name) { return "Hello, " + name + "!";} console.log(greet(profile.name));Hello, Mina!const user = { name: "Asha", badges: ["HTML", "JS"] };
console.log(user.name + " has " + user.badges.length + " badges");Line 1 makes a small user object: one value with named parts, here a name and a list of badges. Line 2 reads the name, counts the badges, and prints Asha has 2 badges. The layout of this code could change. The program would still do the same work.
const price = 12;
const quantity = 2;
const total = price * quantity;
console.log(total);This code is neatly laid out. It prints 24, because 12 times 2 is 24. Prettier can tidy the layout. It cannot tell you whether the quantity should be 2, or whether the price belongs to the right product. Tidy layout helps people spot mistakes. Tests, and other people reading the code, still check that the numbers are right.
With no settings file, Prettier follows these rules:
- Lines stay within 80 characters when possible.
- Each indent is 2 spaces.
- Strings use double quotes.
- Statements end with a semicolon.
- A list or object written over several lines gets a comma after its last item too. In Prettier 3 this setting is called trailing commas, and its default is
all.
A project can change these rules in a file named .prettierrc. The best team rule is simple: agree once, then let the tool do it.
In VS Code, many teams turn on Format on Save. Then the file is tidied each time you save it. A formatter is not the same as a linter. A formatter fixes layout. A linter, such as ESLint, reads your code and warns you about likely mistakes. Linters are the next lesson.
Avoiding clever code
STEP THROUGHClever code packs a lot of work into very few characters. It can feel smart to write, but it is slow to read. Here are some common tricks:
- a ternary inside another ternary. A ternary is the
? :operator: a one-line if/else, likepaid ? "ship" : "wait". &&used to run code, instead of to join two true/false checks,!!valueto turn any value into true or false,~~xto cut the decimal part off a number,- long chains of one-letter names.
These tricks have uses in advanced code. But when a plain if says the same thing, the plain if is easier to read.
An inside joke is funny to the people who know the story. Everyone else is lost. Before they can laugh, someone has to explain the whole story to them.
- In real life: The person who made the joke laughs right away
- In JavaScript: The writer remembers the trick
- In real life: New friends need the whole story first
- In JavaScript: Readers must work out the operators before they see the logic
- In real life: A joke everyone gets lets everyone join in
- In JavaScript: Plain if statements let anyone change the code safely
function canShowCheckout(hasItems, isOffline) {
if (isOffline) {
return false;
}
return hasItems;
}
console.log(canShowCheckout(true, true));
console.log(canShowCheckout(true, false));The first call passes true, true: there are items, but the device is offline. The if on line 2 is true, so line 3 returns false and the function stops there. The second call is online, so it skips the if, reaches line 6, and returns true.
This pattern is called a guard clause: an early return for a case that cannot go on. Use one when it keeps the main path of the function short and flat.
Now compare a clever function with a clear one. Both are real functions, and the lesson's tests run both with many inputs. They always give the same message. The question is: which one would you rather change next month?
&&, ? :, and ||. On the right, each if handles one case. Both give the same message.Pick a cart. Both functions really run, and both print the same shipping message. The question is which one you can read faster.
script
function shippingMessageClever(itemCount, isMember) { return ( (itemCount && (isMember ? "Free shipping" : itemCount > 3 ? "Discount shipping" : "Standard shipping")) || "Cart is empty" );} function shippingMessageClear(itemCount, isMember) { if (itemCount === 0) { return "Cart is empty"; } if (isMember) { return "Free shipping"; } if (itemCount > 3) { return "Discount shipping"; } return "Standard shipping";} const isMember = false;console.log(shippingMessageClever(itemCount, isMember));console.log(shippingMessageClear(itemCount, isMember));Where you’ll use this
Style matters anywhere someone reads code:
- your own notes while you fix a bug,
- a pull request: a request that asks your teammates to check your change and add it to the project,
- a tutorial or a team project,
- a file you have not opened for three weeks.
const MAX_RETRY_ATTEMPTS = 3; function canRetryRequest(errorCount, isOffline) { if (isOffline) { return false; } return errorCount < MAX_RETRY_ATTEMPTS;}MAX_RETRY_ATTEMPTSis a fixed setting, so its name is in capitals.canRetryRequeststarts withcan, so you know it answers yes or no.isOfflinereads naturally inside anif.- The early
returnon line 5 handles the special case first, so the last line stays simple.
Apps make this kind of decision all the time. When a request to a server fails, the app can try again. Trying again is called a retry. A retry can help when the problem was short. It cannot help while the device is offline. So the function checks the offline case first, then checks the normal limit.
This replays a real function call. The early return gives the offline case its own short check, before the limit check.
script
function canRetryRequest(errorCount, isOffline) { if (isOffline) { return false; } return errorCount < 3;} const isOffline = false;console.log(canRetryRequest(errorCount, isOffline));With one failed try and the device online, the replay prints true. With three failed tries, it prints false. With the device offline, it also prints false, because the early return handles that case first.
const menuItems = ["tea", "coffee"];
const sortedMenuItems = [...menuItems].sort();
console.log(menuItems.join(", "));
console.log(sortedMenuItems.join(", "));sort() puts an array in order, and it changes the array you call it on. So line 2 makes a copy first. In [...menuItems], the three dots are the spread syntax: they copy every item into a new array. Then sort() changes only the copy.
Line 4 prints tea, coffee: the original order. Line 5 prints coffee, tea: the sorted copy. The two names tell you which array is the original and which one is sorted. This habit stops you from changing a list that another part of the page still needs.
Before you share code, ask four questions:
- Do the names say what each value is for?
- Did the formatter run?
- Do the comments say why?
- Is any line so clever that a beginner would get stuck on it?
Common misconceptions
“Style is just personal taste.”
Some choices are taste. But using one style everywhere is useful. When a team agrees once, nobody has to argue about spaces again, and everyone can focus on what the code does.
“Shorter code is always better.”
Short code is good when it is still easy to read. When one short line hides three decisions, a few extra lines make it clearer.
“Prettier will make my code good.”
Prettier only fixes layout. It does not pick better names, remove out-of-date comments, or turn a nested ternary into an if statement.
“Comments can fix confusing code.”
First try clearer names and simpler steps. Use comments for things the code cannot show, like a reason. Don't use them to explain code that could simply be clearer.
“Readable code does not need tests.”
Clear code helps people think about it. Tests prove what it does. This lesson's tests check that the renamed function and the clear shipping function give the same results as the originals.
Practice: style decisions
5 EXERCISESTry each task before you open the hints. The answer box checks an exact output or a short answer. The real skill is being able to say why you made your choice.
The program works, but arr2 and x don't say what they hold. What clearer name could replace x?
const arr2 = ["draft", "sent", "archived"];
const x = arr2.length;
console.log(x);const statuses = ["draft", "sent", "archived"];
const statusCount = statuses.length;
console.log(statusCount);statuses says what the list holds, and statusCount says the number is a count. The program still prints 3.
Rewrite the ternary as an if statement. What should your clear version print for this array?
const names = ["Ada", "Mina"];
const label = names.length ? names.join(" & ") : "Nobody";
console.log(label);const names = ["Ada", "Mina"];
let label;
if (names.length === 0) {
label = "Nobody";
} else {
label = names.join(" & ");
}
console.log(label);The clear version has more lines, but each part does one job. join(" & ") puts & between the names, so it still prints Ada & Mina.
The comment says what the code does. What should a better comment explain instead?
// Adds 7 because a week has 7 days
const reminderDay = signupDay + 7;// Wait a full week so new users get one weekend before the reminder.
const reminderDay = signupDay + 7;The new comment says why the wait is seven days. The code already shows that 7 is added.
Lay out the code so its shape is clear. Then predict the output, to prove you did not change what it does.
const user={name:"Ada",badges:["HTML","JS","CSS"]};
console.log(user.name + " has " + user.badges.length + " badges");const user = {
name: "Ada",
badges: ["HTML", "JS", "CSS"],
};
console.log(user.name + " has " + user.badges.length + " badges");The object is easier to read now, and the program does the same thing: it prints Ada has 3 badges.
Answer one question at a time. What does the program print?
const paid = true;
const inStock = false;
const message = paid ? (inStock ? "ship now" : "ship tomorrow") : "ask for payment";
console.log(message);paid is true, so JavaScript checks the inner ternary. inStock is false, so the message is ship tomorrow.
Quiz: check your understanding
7 QUESTIONSYour first try counts for the score. Every answer has an explanation. For code questions, follow the values step by step before you choose.
Question 1 of 7A true/false value says whether a modal, a pop-up box, is open. Which name fits it best?
Choose an answer to see the explanation.
Question 2 of 7What does this program print?
Read the code, then predictfunction calculateTotal(price) { return price + 5; } console.log(calculateTotal(10));Choose an answer to see the explanation.
Question 3 of 7What does Prettier mainly do?
Choose an answer to see the explanation.
Question 4 of 7Which comment is most helpful?
Choose an answer to see the explanation.
Question 5 of 7What does this nested ternary print?
Read the code, then predictconst isLoggedIn = true; const hasProfile = false; const page = isLoggedIn ? (hasProfile ? "profile" : "setup") : "sign in"; console.log(page);Choose an answer to see the explanation.
Question 6 of 7Why avoid clever code, even when it works?
Choose an answer to see the explanation.
Question 7 of 7What does this code print?
Read the code, then predictconst users = ["Ada", "Mina", "Bo"]; const hasUsers = users.length > 0; console.log(hasUsers);Choose an answer to see the explanation.
Key takeaways
- Name each value for its job:
orderItems,minimumPrice, andhasCouponare better thanarr2,x, andflag. - Follow the usual name styles: camelCase for variables and functions, PascalCase for classes, UPPER_SNAKE_CASE for fixed settings, is/has/can for true/false values, verbs for functions, and plural words for lists.
- Prettier is a formatter. It fixes layout, not logic. ESLint, in the next lesson, warns you about likely mistakes.
- Good comments say why, warn about surprises, or explain functions that other files use. Delete out-of-date comments and old code left in comments.
- Choose plain
ifstatements over clever tricks, so the next reader can change the code safely.
Remember the one-liner.
Coding style is kindness to the next person who reads your code. Often, that person is you, a few weeks later.
Up next: Linting with ESLint.
Comments that help
SORTA comment is a note for people. JavaScript skips it. The best comments say something the code cannot say by itself, such as:
A useful sticky note stops someone from making a mistake: “Don't unplug, the freezer is defrosting.” A useless one says “This is a plug.” Anyone can already see that.
countThe comment on line 1 repeats what line 2 already shows. The comment on line 4 explains why line 5 exists.
Math.maxgives back the biggest of the numbers you pass it, so the fee is never less than 1.Line 1 sets an order total of 12. Line 3 gives the reason for the smallest fee. Line 4 does the math: 5 percent of 12 is 0.6, and
Math.max(0.6, 1)picks the bigger number, 1. Line 5 prints 1. The math shows what happens. The comment says why.A stale comment is out of date: the code changed, but the comment did not. Here, line 3 promises the newest order first, but line 4 prints oldest. When you see a mismatch like this, fix the code or fix the comment. Always change a comment in the same edit as the code it talks about.
The table lists the common kinds of comments. Read each row as: this kind of comment helps when…, and watch out for…
/** */note above a function// Round down so discount codes never overcharge the shopper.// Add one to count// TODO: Replace the test discount after launch week.// const oldTotal = price * 1.2;// Warning: the API sends cents, not dollars.// Sort newest first (above code actually sorts oldest first)Sort each comment: does it add something useful? Comments that only repeat the code, or are out of date, are noise.