JavaScript Style Guide¶
What's on this page
- Core content for this topic in the Inkorporated enterprise OS.
- Practical guidance, roles, or standards as applicable.
What this enables
- Consistent enterprise operations and decision-making.
- Shared language for humans and cyborg AI agents.
This document outlines the coding standards and best practices for JavaScript development within this project. Adhering to these guidelines ensures code consistency, readability, and maintainability.
Table of Contents¶
- General Principles
- Code Layout
- Naming Conventions
- Documentation and Comments
- Variables and Declarations
- Functions
- Objects and Arrays
- Classes and Prototypes
- Modules
- Asynchronous Programming
- Control Flow
- Error Handling
- Testing
- Security
- Modern Features
- Recommended Tools
General Principles¶
- ECMAScript Standards: Write modern JavaScript, targeting the latest stable ECMAScript versions. Use transpilers (like Babel) only if legacy browser support is strictly required.
- Consistency: Consistency is key. If you edit existing code, follow the existing style.
- Readability: Code is read much more often than it is written. Prioritize clarity over cleverness.
- Functional Style: Prefer pure functions and immutability where possible. Avoid side effects.
Code Layout¶
- Indentation: Use 2 spaces per indentation level. Do not use tabs.
- Line Length: Limit lines to 80 or 100 characters.
- Semicolons: Always use semicolons to avoid Automatic Semicolon Insertion (ASI) pitfalls.
- Quotes: Use single quotes
'for normal strings. Use backticks`for template literals. Avoid double quotes"unless necessary (e.g., in JSON or to avoid escaping). - Braces:
- Use "Egyptian brackets" (opening brace on the same line).
- Always use braces for control structures (
if,else,for,while), even for single-line blocks.
- Spacing:
- Put a space before the leading brace.
- Put a space after control keywords (
if,for, etc.). - No space before function invocation parentheses.
- Space around operators (
=,+,=>, etc.).
- Trailing Commas: Use trailing commas in multi-line object and array literals, and function arguments. This minimizes diff noise.
- Empty Lines:
- Add an empty line between methods in classes and object literals.
- Add an empty line before logical blocks of code.
- End files with a single newline character.
Naming Conventions¶
- Variables/Functions:
camelCase. - Classes/Components:
PascalCase. - Constants:
UPPER_CASE_WITH_UNDERSCORESfor top-level, immutable constants.camelCasefor constants declared inside functions or that are objects/arrays. - Private Properties: Prefix with
_(underscore) for internal/private properties (convention only) or use#private fields if environment supports it. - Booleans: Prefix with
is,has,should, orcan(e.g.,isVisible,hasError). - Filenames:
kebab-case(e.g.,my-script.js,user-profile.js). - Event Handlers: Prefix with
handle(e.g.,handleSubmit,handleInputChange).
Documentation and Comments¶
- JSDoc: Use JSDoc for documenting functions, classes, and complex logic.
- Inline Comments: Use
//for single-line comments. Explain why, not what. - Block Comments: Use
/* ... */for multi-line comments. - TODOs: Use
TODO(User):to mark areas for improvement.
/**
* Fetches user data from the API.
*
* @param {string} userId - The unique identifier of the user.
* @param {object} [options] - Optional configuration.
* @returns {Promise<User>} The user object.
*/
async function fetchUser(userId, options = {}) {
// ...
}
Variables and Declarations¶
- const vs let: Use
constby default. Useletonly if you need to reassign the variable. - No var: Never use
var. It has function scope and hoisting behavior that can lead to bugs. - Declaration: Declare one variable per statement.
- Destructuring: Use destructuring for accessing object properties and array elements when possible.
// Good
const { name, age } = user;
const [first, second] = items;
// Bad
const name = user.name;
const age = user.age;
Functions¶
- Arrow Functions: Use arrow functions
() => {}for callbacks and anonymous functions to preserve lexicalthis. - Function Declarations: Use function declarations for top-level functions or when hoisting is needed.
- Parameters: Use default parameter syntax instead of mutating arguments inside the function.
- Rest Parameters: Use rest parameters
...argsinstead of theargumentsobject. - Complexity: Keep functions small and focused on a single task.
Objects and Arrays¶
- Object Shorthand: Use property shorthand when the property name matches the variable name.
- Computed Properties: Use computed property names
{[key]: value}when creating objects with dynamic keys. - Spreading: Use the spread operator
...to copy objects and arrays (shallow copy). - Array Methods: Prefer array methods (
map,filter,reduce,find,every,some) overforloops.
const item = {
id: 1,
name: 'Widget',
};
// Shallow copy with override
const updatedItem = { ...item, name: 'New Widget' };
Classes and Prototypes¶
- class: Use
classsyntax instead of manipulatingprototypedirectly. - Inheritance: Use
extendsfor inheritance. - Constructor: Initialize properties in the constructor.
- Methods: Do not use arrow functions as class members unless binding is strictly required (it affects performance and inheritance).
Modules¶
- ES Modules: Use standard ES modules (
import/export) over CommonJS (require/module.exports) unless working in a Node.js environment that strictly requires CommonJS. - Named Exports: Prefer named exports over default exports. This improves discoverability and refactoring.
- Imports:
- Put imports at the top of the file.
- Sort imports: Built-in, Third-party, Internal (absolute), Internal (relative).
import fs from 'fs';
import _ from 'lodash';
import { User } from '@/models/User';
import { format } from './utils';
Asynchronous Programming¶
- Async/Await: Prefer
async/awaitover raw Promises (.then(),.catch()) for better readability. - Try/Catch: Use
try/catchblocks to handle errors in async functions. - Parallelism: Use
Promise.all()to run independent promises in parallel.
async function loadData() {
try {
const [users, posts] = await Promise.all([
fetchUsers(),
fetchPosts(),
]);
return { users, posts };
} catch (error) {
console.error('Failed to load data', error);
throw error;
}
}
Control Flow¶
- Comparison: Use strict equality
===and inequality!==. - Ternary: Use ternary operators
condition ? true : falsefor simple assignments. Avoid nested ternaries. - Switch: Use
switchstatements for multiple conditions on the same variable. Always include adefaultcase. - Conditionals: Avoid "Yoda conditions" (
if ('red' === color)). Place the variable on the left.
Error Handling¶
- Throwing: Throw
Errorobjects (or subclasses), not strings.throw new Error('Something went wrong');
- Handling: Handle errors at the appropriate level. Don't swallow errors silently.
- Custom Errors: Create custom error classes for domain-specific errors.
Testing¶
- Framework: Use a modern testing framework like Jest, Vitest, or Mocha.
- Unit Tests: Write unit tests for all utility functions and components.
- Integration Tests: Write integration tests for API interactions and flows.
- Mocks: Mock external dependencies to keep tests fast and deterministic.
- Coverage: Aim for high test coverage, but value meaningful tests over 100% coverage stats.
Security¶
- XSS: Be wary of Cross-Site Scripting. Sanitize user input before rendering it to the DOM. Avoid
innerHTMLordangerouslySetInnerHTMLunless absolutely necessary and input is sanitized (e.g., with DOMPurify). - Dependencies: Regularly audit dependencies (
npm audit) for vulnerabilities. - Sensitive Data: Never commit secrets or keys to the repository.
Modern Features¶
- Optional Chaining: Use
?.to safely access nested properties. - Nullish Coalescing: Use
??to provide default values fornullorundefined(but not0orfalse). - Object.entries/values: Use
Object.keys,Object.values, andObject.entriesfor iterating over objects.
Recommended Tools¶
- Linter:
ESLint. Use standard configs likeeslint-config-airbnb-baseoreslint-config-standard. - Formatter:
Prettier. Integrate with ESLint to avoid conflicts. - Type Checking: While this is a JS guide, consider using JSDoc with TypeScript checking (
// @ts-check) or migrating to TypeScript for larger projects. - Bundler:
Vite,Webpack, orRollup.
Related Interview Questions¶
- Practice Questions: Test your knowledge of Javascript concepts.