JavaScript Naming Conventions
Introduction
Good naming conventions are like clear signposts in your code. They make your code more readable, maintainable, and help other developers (or future you!) understand what's happening without having to decipher cryptic variable names or function identifiers.
In this guide, we'll explore JavaScript naming conventions - the established patterns and practices for naming different elements in your code. Following these conventions will make your code more professional and easier to work with.
Why Naming Conventions Matter
Before diving into the specific conventions, let's understand why they're important:
- Readability: Clear names make code easier to read and understand
- Maintainability: Well-named elements help when debugging or refactoring
- Collaboration: Other developers can understand your code more quickly
- Consistency: A consistent style throughout a codebase reduces cognitive load
General Rules for All JavaScript Names
No matter what you're naming, these general principles apply:
- Be descriptive: Names should clearly indicate what the variable, function, or class does
- Use ASCII letters and digits: Stick to standard English characters
- Avoid single letter names (except in specific contexts like loop counters)
- Don't use reserved keywords like
function
,class
,return
, etc. - Prioritize readability over brevity
Let's look at specific conventions for different code elements:
Variables
camelCase for Variables and Functions
In JavaScript, the standard convention is to use camelCase for variables and functions. This means:
- Start with a lowercase letter
- Each new word starts with an uppercase letter
- No spaces or underscores between words
// Good variable names
let firstName = "John";
let userAge = 25;
let isActive = true;
let calculateTax = function(amount) { /* ... */ };
// Poor variable names
let FirstName = "John"; // Starts with capital (looks like a class)
let user_age = 25; // Uses snake_case instead of camelCase
let n = "John"; // Too short, not descriptive
Be Specific and Contextual
Variables should be named according to what they represent, not their data type or structure:
// Good: descriptive of what the variable contains
let userNames = ["Alex", "Taylor", "Jordan"];
let productPrice = 19.99;
let isLoggedIn = true;
// Poor: focuses on data type rather than meaning
let stringArray = ["Alex", "Taylor", "Jordan"];
let number = 19.99;
let boolean = true;
Booleans: Use Prefixes
For boolean variables, using prefixes like is
, has
, can
, or should
makes the code more readable:
// Good boolean names
let isVisible = true;
let hasPermission = false;
let canEdit = true;
let shouldRefresh = false;
// Without these prefixes, the purpose is less clear
let visible = true; // Less obvious it's a boolean
let permission = false; // Could be an object instead of a boolean
Constants
ALL_UPPER_CASE for Constants
Use UPPERCASE with underscores for named constants and configuration values:
// Constants using uppercase
const MAX_ITEMS_PER_PAGE = 20;
const API_BASE_URL = "https://api.example.com";
const DEFAULT_TIMEOUT = 3000;
// Not recommended for constants
const maxItemsPerPage = 20; // Looks like a regular variable
However, this convention is typically used for "true" constants that represent a fixed value. Object constants that might have properties modified often use camelCase instead:
// Object constants often use camelCase
const configOptions = {
timeout: 3000,
retries: 3
};
Functions
camelCase for Functions
Like variables, functions should use camelCase:
// Good function names
function calculateTotal(items) { /* ... */ }
function getUserData(userId) { /* ... */ }
function isValidEmail(email) { /* ... */ }
// Function names should describe the action they perform
function process() { /* ... */ } // Too vague
function doIt(data) { /* ... */ } // Meaningless
Verb Prefixes for Functions
Since functions perform actions, beginning them with a verb makes their purpose clearer:
// Functions with verb prefixes
function getUser(id) { /* ... */ } // Retrieves something
function calculateTotal(items) { /* ... */ } // Calculates something
function validateInput(form) { /* ... */ } // Validates something
function setPreference(name, value) { /* ... */ } // Sets something
Common verb prefixes and their meanings:
get
: retrieve a valueset
: assign a valueis/has/can
: return a booleancalculate/compute
: perform a calculationhandle
: deal with an eventcreate
: create a new instanceupdate
: modify an existing instance
Event Handler Naming
For event handlers, a common convention is to use the prefix handle
or on
:
// Event handler naming
function handleClick(event) { /* ... */ }
function onSubmit(formData) { /* ... */ }
function handleUserLogin(credentials) { /* ... */ }
Classes
PascalCase for Classes
Classes and constructor functions should use PascalCase (capitalize the first letter of each word):
// Good class names
class UserProfile {
constructor(user) {
this.user = user;
}
}
class PaymentProcessor {
processPayment(amount) {
// Process payment
}
}
// Poor class names
class userProfile {} // Starts with lowercase
class payment_processor {} // Uses snake_case
File Names for Classes
When a file contains a single class, the file name often matches the class name:
// File: UserProfile.js
class UserProfile {
// ...
}
export default UserProfile;
Private Properties and Methods
Use Underscore Prefix for "Private" Members
While JavaScript doesn't have true private members (until private fields using #
), a common convention is to use an underscore prefix to indicate that a property or method should be treated as private:
class User {
constructor(name) {
this.name = name;
this._password = null; // Indicates this should not be accessed directly
}
_encryptPassword(password) { // "Private" method
// Encryption logic...
return "encrypted";
}
setPassword(password) {
this._password = this._encryptPassword(password);
}
}
With newer JavaScript syntax, you can use the #
symbol for actual private fields:
class User {
#password; // Truly private field
constructor(name) {
this.name = name;
}
#encryptPassword(password) { // Private method
return "encrypted";
}
setPassword(password) {
this.#password = this.#encryptPassword(password);
}
}
File Names
use-kebab-case.js or camelCase.js
For JavaScript file names, two conventions are common:
-
kebab-case: Words separated by hyphens
user-profile.js
payment-processor.js
form-validation.js -
camelCase: Similar to variable naming
userProfile.js
paymentProcessor.js
formValidation.js
Component files in React or similar frameworks often use PascalCase to match the component name:
UserProfile.jsx
PaymentProcessor.js
FormValidation.tsx
Practical Examples
Let's see these conventions applied in a real-world example. Here's a user management module following proper naming conventions:
// Constants
const MAX_LOGIN_ATTEMPTS = 5;
const DEFAULT_USER_ROLE = "user";
// Class using PascalCase
class UserManager {
#activeUsers; // Private field
constructor() {
this.#activeUsers = new Map();
}
// Method using camelCase with verb prefix
addUser(userData) {
const { username, email } = userData;
if (!this.#isValidEmail(email)) {
throw new Error("Invalid email format");
}
const newUser = {
username,
email,
role: DEFAULT_USER_ROLE,
loginAttempts: 0,
isActive: true,
createdAt: new Date()
};
this.#activeUsers.set(username, newUser);
return newUser;
}
// Private method with # syntax
#isValidEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
// Boolean method using "is" prefix
isUserActive(username) {
return this.#activeUsers.has(username) &&
this.#activeUsers.get(username).isActive;
}
// Method using get prefix
getUserByUsername(username) {
return this.#activeUsers.get(username);
}
// Event handler using handle prefix
handleLoginAttempt(username, password) {
const user = this.#activeUsers.get(username);
if (!user) {
return { success: false, message: "User not found" };
}
// Simulating password check
const isPasswordCorrect = this.#verifyPassword(username, password);
if (!isPasswordCorrect) {
user.loginAttempts++;
if (user.loginAttempts >= MAX_LOGIN_ATTEMPTS) {
user.isActive = false;
return {
success: false,
message: "Account locked due to too many failed attempts"
};
}
return { success: false, message: "Incorrect password" };
}
// Reset login attempts on successful login
user.loginAttempts = 0;
return { success: true, user };
}
// Another private method
#verifyPassword(username, password) {
// In a real app, this would check against stored password
return password.length > 0; // Simplified for example
}
}
// Usage example
const userManager = new UserManager();
const newUser = userManager.addUser({
username: "jsmith",
email: "[email protected]"
});
const loginResult = userManager.handleLoginAttempt("jsmith", "password123");
if (loginResult.success) {
console.log("User logged in successfully!");
} else {
console.log(`Login failed: ${loginResult.message}`);
}
This example demonstrates how proper naming makes code more readable and self-documenting.
Naming in Different Contexts
React Components
In React applications, components typically use PascalCase:
// Component name and file both use PascalCase
// UserProfile.jsx
function UserProfile(props) {
return (
<div className="user-profile">
<h2>{props.user.name}</h2>
<p>{props.user.email}</p>
</div>
);
}
// CSS classes within JSX often use kebab-case
// Props use camelCase
Redux Actions/Reducers
In Redux, there are special conventions:
// Action types are often UPPER_SNAKE_CASE
const USER_LOGIN_REQUEST = 'USER_LOGIN_REQUEST';
const USER_LOGIN_SUCCESS = 'USER_LOGIN_SUCCESS';
const USER_LOGIN_FAILURE = 'USER_LOGIN_FAILURE';
// Action creators use camelCase
function loginUser(credentials) {
return {
type: USER_LOGIN_REQUEST,
payload: credentials
};
}
// Reducer uses camelCase
function userReducer(state = initialState, action) {
switch (action.type) {
case USER_LOGIN_SUCCESS:
return {
...state,
isLoggedIn: true,
userData: action.payload
};
// More cases...
default:
return state;
}
}
Summary
Proper naming conventions make your code more professional, easier to read, and simpler to maintain. Here's a quick recap:
- Variables and Functions: camelCase
- Classes and Components: PascalCase
- Constants: UPPER_SNAKE_CASE
- Private Properties: _underscorePrefix (older) or #privateField (newer)
- Boolean Variables: isActive, hasPermission (use appropriate prefixes)
- Functions: Use verb prefixes (get, set, is, has, calculate, etc.)
- File Names: kebab-case.js or camelCase.js (components often use PascalCase.jsx)
Remember that consistency within a project is more important than strictly following any specific convention. If your team or project has established naming patterns, it's usually best to follow those for consistency, even if they differ from the common conventions described here.
Additional Resources and Exercises
Resources
- Google JavaScript Style Guide - Google's guidelines for JavaScript code style
- Airbnb JavaScript Style Guide - A popular style guide in the JavaScript community
- Clean Code JavaScript - Adapts principles from Clean Code for JavaScript
Exercises
- Refactoring Practice: Take the following code snippet with poor naming and refactor it to follow proper conventions:
const x = 500;
const y = 10;
let z = [];
function a(b, c) {
let d = b * c;
let e = d > x;
z.push({val: d, ok: e});
return e;
}
let f = false;
for(let i=0; i<y; i++) {
let g = Math.random() * 100;
let h = a(g, 5);
if (h) f = true;
}
-
Component Naming: Create naming conventions for a fictional e-commerce application. Come up with appropriate names for:
- User authentication components
- Shopping cart functionality
- Product listing and details
- Order processing functions
-
Code Review: Review a piece of your own code or an open-source project and identify 3-5 examples where naming could be improved. Suggest better alternatives.
By following these naming conventions consistently, you'll write code that's more professional, easier to understand, and simpler to maintain - skills that will serve you well throughout your career as a JavaScript developer.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)