Practical guide to JavaScript best practices.
Neeraj Swarnkar
Sr. Staff Engineer - Full Stack / Front End at Eagleview | Ex-Cisco | Ex-HP | Trainer | React, Angular, Svelte, Node, Typescript, Javascript
Introduction
Following JavaScript best practices is crucial for writing clean, efficient, and maintainable code. These practices enhance code readability, improve performance, and facilitate collaboration. This page outlines key best practices and provides code examples.
Avoid Globals (Use let and const)
Code Example:
// Bad: Global variable
var myGlobalVariable = 'some value';
// Good: Local variable
function processData() {
let dataValue = 'local value'; // Can be reassigned
const MAX_VALUE = 100; // Cannot be reassigned
console.log(dataValue, MAX_VALUE);
}
Avoid loose equality (double equals)
Code Example:
// Loose Equality (Avoid)
console.log(1 == '1'); // true (string '1' is coerced to number 1)
console.log(0 == false); // true (false is coerced to 0)
console.log(null == undefined); // true (a special case)
console.log([] == false) // true ([] is coerced to 0, false is coerced to 0)
console.log([] == ![]) // true ([] is coerced to 0, ![] is coerced to false which is 0)
console.log(null == 0) // false
console.log(undefined == 0) // false
// Strict Equality (Use This)
console.log(1 === '1'); // false (different types)
console.log(0 === false); // false (different types)
console.log(null === undefined); // false
console.log([] === false) // false
console.log([] === ![]) // false
console.log(null === 0) // false
console.log(undefined === 0) // false
// Special cases to be aware of
console.log(NaN == NaN) // false
console.log(NaN === NaN) // false, the only way to check for NaN is Number.isNaN()
console.log(Number.isNaN(NaN)) // true
Avoid JavaScript for Styling
Code Example:
// Bad: Manipulating CSS directly
const element = document.getElementById('myElement');
element.style.color = 'red';
// Good: Using ClassList API
const element = document.getElementById('myElement');
element.classList.add('red');
Use Shorthands Carefully
Code Example:
let value = true;
// Longhand
if (value === true) {
// ...
}
// Shorthand
if (value) {
// ...
}
// Longhand (Function Declaration)
function addNumbers(a, b) {
return a + b;
}
// Shorthand (Arrow Function)
const addNumbers = (a, b) => a + b;
//Shorthand (Ternary Operator)
const age = 20
const type = age >= 18 ? 'Adult' : 'Child'
Meaningful Names (Avoid Vague Terms)
// Bad:
let data = [1, 2, 3];
function process(d) { /* ... */ }
// Good:
let productQuantities = [1, 2, 3];
function calculateTotalQuantity(quantities) { /* ... */ }
class ProductManager{
}
Initialize Variables
Code Example:
// Bad:
let myVariable;
// Good:
let myVariable = null;
let myArray = [];
Commenting and Documentation (Use JSDoc)
Code Example:
/**
* Calculates the area of a rectangle.
* @param {number} width - The width of the rectangle.
* @param {number} height - The height of the rectangle.
* @returns {number} The area of the rectangle.
* @throws {Error} If width or height is not a number.
* @todo Implement input validation for negative values.
*/
function calculateRectangleArea(width, height) {
if (typeof width !== 'number' || typeof height !== 'number') {
throw new Error('Width and Height must be numbers.')
}
return width * height;
}
Do Not Use the Object Constructor
Code Example:
// Bad:
const person = new Object();
person.name = 'John';
// Good:
const person = { name: 'John' };
Use for...of Instead of for Loops
Code Example:
const numbers = [1, 2, 3, 4, 5];
// Bad:
for (let i = 0; i < numbers.length; i++) {
console.log(numbers[i]);
}
// Good:
for (const number of numbers) {
console.log(number);
}
Avoid Creating Irrelevant Classes (Single Responsibility Principle)
Code Example:
// Bad: A class that handles both user data and UI updates
// class UserInterfaceManager {
// constructor(userData) { /* ... */ }
// updateDisplay() { /* ... */ }
// saveUserData() { /* ... */ }
// }
// Good: Separate classes for data handling and UI
class UserData {
constructor(name, email) {
this.name = name;
this.email = email;
}
}
class UserDisplay {
displayUser(userData) {
console.log('User: ', userData.name)
}
}
const user = new UserData("test", "[email protected]")
const display = new UserDisplay()
display.displayUser(user)
Class Declaration and Hoisting
Code Example:
// Bad:
// const myInstance = new MyClass(); // ReferenceError: Cannot access 'MyClass' before initialization
// class MyClass {
// constructor() {}
// }
// Good:
class MyClass {
constructor(name) {
this.name = name
}
getName(){
return this.name
}
}
const myInstance = new MyClass("test");
console.log(myInstance.getName())
领英推荐
Helper Functions for Common Tasks
Code Example:
// Helper function to format dates
function formatDate(date) {
return new Date(date).toLocaleDateString();
}
// Usage
const formattedDate = formatDate('2024-10-27');
console.log(formattedDate); // Output depends on locale
Asynchronous Code (Promises, async/await)
Code Example:
async function fetchData() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error fetching data:', error);
}
}
fetchData();
Error Handling (try...catch)
Code Example:
function divide(a, b) {
try {
if (b === 0) {
throw new Error('Division by zero!');
}
return a / b;
} catch (error) {
console.error('An error occurred:', error.message);
return NaN; // Or handle the error in another way
}
}
console.log(divide(10, 0)); // Output: An error occurred: Division by zero! NaN
Use the Appropriate Log Method
Code Example:
console.log('This is a regular log message.');
console.warn('This is a warning message.');
console.error('This is an error message.');
console.debug('This is a debug message.'); // Usually hidden unless debug mode is enabled
Use Safe and Reliable APIs
Code Example:
// Bad: Using XMLHttpRequest (XHR)
// const xhr = new XMLHttpRequest(); // ...
// Good: Using fetch()
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
Use Object.hasOwn() vs Object.prototype.hasOwnProperty()
Code Example:
if (Object.hasOwn(obj, 'prop')) {
console.log('Property exists');
}
Reference: MDN - Object.hasOwn()
Minimize Branching with Number()
Code Example:
console.log(Number(undefined)); // NaN
console.log(Number(null)); // 0
console.log(Number(true)); // 1
console.log(Number(false)); // 0
Reference: MDN - Number()
Use Array Methods Like every() and some()
Code Example:
const numbers = [1, 2, 3, 4, 5];
console.log(numbers.some(num => num > 3)); // true
console.log(numbers.every(num => num > 0)); // true
Reference: MDN - Array.every()
Document JavaScript Code Properly
JSDoc Example:
/**
* Adds two numbers.
* @param {number} a - The first number.
* @param {number} b - The second number.
* @returns {number} Sum of the two numbers.
* @todo Handle non-numeric inputs.
*/
function add(a, b) {
return a + b;
}
Reference: JSDoc
This is a more detailed and practical guide to JavaScript best practices. Whether you're a seasoned JavaScript developer or just starting your coding journey. Thanks!
Yours !!
Neeraj S