JavaScript Clean Code: The Ultimate Guide for Developers
Tags: javascript, cleancode, codenewbie, webdev
Published: 2023-11-05 05:13:12

### Howdy, Fellas!

In the realm of web development, we often encounter numerous JavaScript resources and tutorials, each offering a unique approach to coding. While these resources provide valuable insights, they can sometimes introduce challenges in code comprehension due to inconsistent naming conventions and unclear structures.

In this comprehensive guide, we'll dive into the art of crafting clean and maintainable JavaScript and TypeScript code. We'll cover best practices for functions, variables, and methods, ensuring your code is not only efficient but also easily understood by both you and your collaborating developers. Let's enhance your coding skills and optimize your development process for a more efficient and enjoyable coding experience.

***

**Variable Names:** As a web developer, one of the fundamental principles for writing clean and maintainable code is to use meaningful variable and function names. Code readability is crucial for collaboration and for your own future reference, and using descriptive names that accurately convey the purpose and functionality of your variables and functions is a significant step in achieving this goal. 

Avoid the temptation to use single-letter variable names or cryptic abbreviations that can make your code difficult to read and understand. When it comes to variable names, you should always aim for clarity and descriptiveness. 

Let's explore this concept further using JavaScript and TypeScript:
```javascript
// Poor approach
var c;
var d;
var cd;
var u;

// Best approach
let counter = 0;
let date = null;
let currentDate = null;
let user = "";

```
**Boolean Variables:** When working with boolean variables in JavaScript and TypeScript, it's essential to maintain clarity in your code. Instead of using single letters or ambiguous words, consider representing boolean variables as questions or statements that clearly convey their purpose. TypeScript adds a powerful layer of static typing to JavaScript, further enhancing code readability and maintainability.

Here's an example of how to write clean and clear boolean variables in TypeScript:
```javascript
var v=false;
var w=false;
var c=false;
var l=false;

// Best approach for this
let isValid: boolean = false;
let isWritable: boolean = false;
let isCleared: boolean = false;
let isLoading: boolean = false;

```
***

**Numeric Variables:** When dealing with numeric variables in your JavaScript and TypeScript code, it's crucial to use meaningful and descriptive variable names. This practice improves code readability and maintenance, making it easier for you and your team to understand the purpose of these variables. Instead of using cryptic variable names like bMax, bMin, and bTot, opt for names that clearly convey their intent. Additionally, leverage TypeScript's type system to provide type safety, which helps catch potential bugs during development.

Here's an improved example using TypeScript:
```javascript
var bMax=false;
var bMin=false;
var bTot=false;

// Best approach for this case
let booksMaximum: number = 50;
let booksMinimum: number = 1;
let booksTotal: number = 51;

```
***
**Array Names:** When working with arrays or lists in JavaScript and TypeScript, it's essential to choose meaningful and descriptive names for your variables. Consider using camelCase for naming conventions and provide clear names that indicate the purpose of the array. Here's how you can improve your code with TypeScript:

```typescript
// Poor naming conventions and no type information
var f = ["Mango", "Papaya", "Apple", "Banana"];
var c = ["Mazda", "Toyota", "Nissan", "Ford"];
var m = ["Fish", "Pork", "Beef", "Chicken"];

// Best approach for the case of lists or arrays
let fruits: string[] = ["Mango", "Papaya", "Apple", "Banana"];
let carBrands: string[] = ["Mazda", "Toyota", "Nissan", "Ford"];
let meatsType: string[] = ["Fish", "Pork", "Beef", "Chicken"];
```

***

**Keep functions short and focused:** One of the core principles of writing clean and maintainable code in JavaScript and TypeScript is keeping your functions concise and focused. To achieve this, break down larger functions into smaller, modular counterparts, each dedicated to a single, well-defined task. This approach enhances code modularity, making it easier to test and maintain.

Here's an example that demonstrates how to refactor a JavaScript function into TypeScript, following the "short and focused" principle:

**Before Refactoring (JavaScript):**

```javascript
function calculateOrderTotal(order) {
  let total = 0;
  for (const item of order.items) {
    total += item.price * item.quantity;
  }

  if (order.promoCode) {
    total -= total * 0.1;
  }

  if (total > 1000) {
    total -= 100;
  }

  return total;
}
```

**After Refactoring (TypeScript):**

```typescript
interface Order {
  items: Array<{ price: number; quantity: number }>;
  promoCode?: string;
}

function calculateOrderTotal(order: Order): number {
  const subtotal = calculateSubtotal(order.items);
  const discountedTotal = applyPromoCode(subtotal, order.promoCode);
  return applyDiscountIfApplicable(discountedTotal);
}

function calculateSubtotal(items: Array<{ price: number; quantity: number }>): number {
  return items.reduce((acc, item) => acc + item.price * item.quantity, 0);
}

function applyPromoCode(subtotal: number, promoCode?: string): number {
  if (promoCode) {
    return subtotal - subtotal * 0.1;
  }
  return subtotal;
}

function applyDiscountIfApplicable(total: number): number {
  if (total > 1000) {
    return total - 100;
  }
  return total;
}
```

***

**Use comments in your code:** Using comments to explain your code's intent is a crucial practice in maintaining clean and understandable code. Well-placed comments can provide clarity to both yourself and other developers who may work with your code in the future. They should describe the purpose of the code, its expected behavior, and any significant information that might not be evident from the code alone.

Here's an example in TypeScript illustrating the use of comments:

```typescript
// Define a custom type for the array objects structure
type MyObject = {
  id: number;
  name: string;
};

/**
 * Sort an array of MyObject by their 'id' property in ascending order.
 *
 * @param array - The array to be sorted.
 * @returns A new array with objects sorted by 'id'.
 */
function sortObjectsById(array: MyObject[]): MyObject[] {
  return array.slice().sort((a, b) => a.id - b.id);
}

const arrDevelopers = [
  { id: 3, name: "Jorgel", language: "PHP" },
  { id: 0, name: "Eleazar", language: "Python" },
  { id: 1, name: "Hector", language: "Java" },
  { id: 2, name: "Alvison", language: "Golang" },
  { id: 4, name: "Bill", language: "JavaScript" },
];

sortObjectsById(arrDevelopers)

```

***

**Use WhiteSpace in your code:** Whitespace is an important aspect of writing clean and maintainable code in JavaScript and TypeScript. Properly utilizing line breaks, indentation, and blank lines enhances code readability and makes it more visually appealing. Group related lines of code together and separate them from other blocks of code with blank lines. Let's take a look at an example in TypeScript:

```typescript
function calculateTotalPrice(items: Item[]): number {
    let totalPrice = 0;

    for (const item of items) {
        totalPrice += item.price * item.quantity;
    }

    return totalPrice;
}

class Item {
    constructor(public name: string, public price: number, public quantity: number) {}
}

const shoppingCart: Item[] = [
    new Item("Laptop", 1000, 2),
    new Item("Mouse", 30, 3),
    new Item("Keyboard", 50, 1),
];

const total = calculateTotalPrice(shoppingCart);

console.log(`Total price: $${total}`);
```
***

**Avoiding using nested conditional statements:** Use early returns or guard clauses to improve code readability and reduce complexity. Instead of multiple nested if-else statements, create functions or methods that return early when conditions are met. This approach enhances code organization and simplifies understanding for developers.

Here's an example in TypeScript demonstrating the use of early returns:

```typescript
function calculatePrice(quantity: number, price: number, discountApplied: boolean): number {
    if (quantity <= 0) {
        return 0; // Guard clause to handle invalid input
    }

    let total = quantity * price;

    if (discountApplied) {
        total *= 0.9; // Apply a 10% discount
    }

    return total;
}
```
***

**Avoid Global Variables:** A key principle for clean and maintainable JavaScript and TypeScript code is reducing global variable usage. Relying too much on globals can result in naming conflicts, unintended side effects, and code complexity. To address these concerns, opt for closures or module patterns to encapsulate your code and avoid global namespace pollution.

Here's an example demonstrating how to avoid global variables by encapsulating functionality within a TypeScript module:

```typescript
// Instead of global variables, encapsulate your code in a module
namespace MyModule {
  // Private variable accessible only within the module
  let counter = 0;

  // Public function to interact with the module
  export function incrementCounter(): void {
    counter++;
  }

  // Public function to retrieve the counter value
  export function getCounterValue(): number {
    return counter;
  }
}

// Usage of the module functions
MyModule.incrementCounter();
console.log(MyModule.getCounterValue()); // Output: 1
```
***
**Use const and let instead of var:** When declaring variables in JavaScript or TypeScript, it's best practice to utilize const and let rather than var. This choice enhances code readability, enforces block scoping, and mitigates the risk of accidental variable reassignment. By using const for values that won't change and let for variables that need to be reassigned, you can create cleaner and more predictable code. Here's an example in TypeScript:

```typescript
// Using const for constants
const pi = 3.14;
const appName = "MyApp";

// Using let for variables
let counter = 0;
let username = "JohnDoe";

// Attempting to reassign a constant will result in a compile-time error
// pi = 3.14159; // Error: Cannot assign to 'pi' because it is a constant.

// Reassigning a variable is perfectly valid
counter = 1;
username = "JaneDoe";
```
***

**Use Template Literals:** When it comes to writing clean and maintainable code in JavaScript and TypeScript, one essential practice is to use template literals for string interpolation. Template literals provide a concise and readable way to embed variables and expressions within strings, eliminating the need for messy concatenation or complex string manipulation. They are enclosed within backticks and can contain placeholders for variables or expressions enclosed in "`${}`". 

Here's an example in EcmaScript:

```typescript
// Define first and last names
const firstName = "John";
const lastName = "Doe";

// Create the full name using a template literal
const fullName = `My name is ${firstName} ${lastName}.`;

// Log the full name to the console
console.log(fullName);

```

***

**Use Arrow Functions:** When working with simple callback functions in JavaScript and TypeScript, it's best practice to utilize arrow functions. Arrow functions offer a more concise and readable syntax compared to traditional function expressions. They automatically bind to the surrounding context, which can help reduce code verbosity. Here's an example in TypeScript to illustrate this:

```typescript
// Traditional function expression
const add = function (a: number, b: number): number {
  return a + b;
};

// Arrow function for the same task
const add = (a: number, b: number): number => a + b;
```
***

**Use Object Destructuring:** In JavaScript and TypeScript, clean and maintainable code hinges on object destructuring. This technique streamlines property access, enhancing code readability and reducing redundancy, especially when dealing with nested objects. Instead of accessing properties individually, object destructuring extracts the necessary properties, promoting cleaner and more intuitive code.

Here's a TypeScript example to illustrate the concept:

```typescript
// A sample user object
const user = {
  id: 1,
  name: 'John Doe',
  email: 'john@example.com',
  address: {
    street: '123 Main St',
    city: 'Anytown',
    zipCode: '12345',
  },
};

// Without destructuring
const userName = user.name;
const userCity = user.address.city;

// With destructuring
const { name, address: { city } } = user;

console.log(`User Name: ${name}`);
console.log(`User City: ${city}`);
```
***
**Function Names:** When naming functions in JavaScript and TypeScript, use clear verb-noun combinations for function names to convey their purpose effectively, making code more understandable for developers. For example, if you have a function that calculates the total price of items in a shopping cart, a well-named function might be `calculateTotalPrice`:

```typescript
function calculateTotalPrice(items: Item[]): number {
  // Logic to calculate the total price
}
```
***
**Bonus:** Optimize your code further by utilizing EcmaScript mode and arrow functions. Here are some illustrative examples:
```javascript
const paymentUpdatedMessage = 'Payment has been updated!';
function payment(){
console.log(paymentUpdatedMessage);
}


// Best approach with regular JS and ES6
function updatePayment(){
console.log(paymentUpdatedMessage);
}

// Best approach using EcmaScript
const updatePayment = () =>
console.log(paymentUpdatedMessage);
}

```
***
In conclusion, clean and maintainable code is essential for proficient web development. This ultimate guide for JavaScript and TypeScript emphasizes best practices to keep your codebase efficient, scalable, and collaborative. By consistently applying principles like DRY, KISS, SOLID, and focusing on meaningful naming and documentation, you'll elevate your code's quality and save time, making you a valuable team member.

So, keep refining your coding skills, stay updated with industry trends, and continue the journey towards writing cleaner, more elegant code. Happy coding!

❤️ Enjoyed the article? Your feedback fuels more content.
💬 Share your thoughts in a comment.
🔖 No time to read now? Well, Bookmark for later.
🔗 If it helped, pass it on, dude!