DEV Community

Cover image for Writing Clean Javascript Code for Beginners
Chrysilla Mayasari
Chrysilla Mayasari

Posted on • Edited on

Writing Clean Javascript Code for Beginners

What is Clean Code?

This term might have different meaning for developers. Although there are several best practices you can follow but there is no exact definition for clean code.

But for what I have learned and read, this is what a clean code is,

Clean code is code that is easy to understand, straightforward and consistent, therefore it would be reusable and refactorable.

This is important because as a developer, most of the time we will collaborate with other developers so we need to make sure that our code can be understood easily by everyone in team.

Now, let's take a look on what are the things we must do to write clean code in Javascript by writing examples code related to a Restaurant application.

1. Variables

  • Use meaningful and self descriptive names.

⛔️

let rn = 'Bambang Restaurant';
Enter fullscreen mode Exit fullscreen mode


let restaurantName = 'Bambang Restaurant';
Enter fullscreen mode Exit fullscreen mode
  • Usually we use camelCase for variables and functions, and PascalCase for class. Sometimes you can also find variables in UPPERCASE, which means the variable is a constant.

⛔️

let IsMENUAvAiLaBle = true;
Enter fullscreen mode Exit fullscreen mode


let isMenuAvailable = true;
Enter fullscreen mode Exit fullscreen mode

2. Function

  • Just like variables, function should have self descriptive name.

⛔️

function addToList(list, menu) {
  // ...
}
addToList('Indonesian', 'Nasi Goreng');
Enter fullscreen mode Exit fullscreen mode


function addMenuToList(menu, list) {
  // ...
}
addMenuToList('Nasi Goreng', 'Indonesian');
Enter fullscreen mode Exit fullscreen mode
  • Ideally, function should only have two or fewer parameters. If you have more than two, you should consider using object.

⛔️

function createMenu(title, description, price, isAvailable) {
  // ...
}
createMenu('Rendang', 'Most delicious dish in the world', 50000, true);
Enter fullscreen mode Exit fullscreen mode


function createMenu({title, description, price, isAvailable}) {
  // ...
}
createMenu({
  title: 'Rendang',
  description: 'Most delicious dish in the world',
  price: 50000,
  isAvailable: true
});
Enter fullscreen mode Exit fullscreen mode
  • Function should only do one thing.

⛔️

function advertiseMenus(menus) {
  menus.forEach(menu => {
    const menuList = data.find(menu);
    if(menuList.isOpen()){
      advertise(menu);
    }
  })
}
Enter fullscreen mode Exit fullscreen mode


function advertiseAvailableMenus(menus) {
  menus.filter(isAvailableMenu).forEach(advertise);
}

function isAvailableMenu(menu) {
  const menuList = data.find(menu);
  return menuList.isOpen();
}
Enter fullscreen mode Exit fullscreen mode
  • Set default object with Object.assign().

⛔️

const restaurantSettings = {
  name: 'Bambang Restaurant',
  details: null,
  category: ['Fine Dining']
}

function createRestaurant(settings) {
  settings.name = settings.name || 'Lorem Ipsum Restaurant';
  settings.details = settings.details || 'Lorem ipsum dolor sit amet.'
  settings.category = settings.category || ['Casual Dining']
  settings.isOpen = settings.isOpen || false
}

createRestaurant(restaurantSettings);
Enter fullscreen mode Exit fullscreen mode


const restaurantSettings = {
  name: 'Bambang Restaurant',
  details: 'All you can eat and drink',
  category: ['Fine Dining']
}

function createRestaurant(settings) {
  let finalSettings = Object.assign({
    name: 'Lorem Ipsum Restaurant',
    details: 'Lorem ipsum dolor sit amet.',
    category: ['Casual Dining']
    isOpen: false
  }, settings);

  return finalSettings;
}

createRestaurant(restaurantSettings);
Enter fullscreen mode Exit fullscreen mode

3. Conditional

  • Encapsulate conditionals.

⛔️

if (menu.discountPrice && paymentMethod.isAvailable) {
  // ...
}
Enter fullscreen mode Exit fullscreen mode


function shouldShowPromoRibbon(menu, paymentMethod) {
  return menu.discountPrice && paymentMethod.isAvailable;
}

if (shouldShowPromoRibbon(menuInstance, paymentMethodInstance)) {
  // ...
}
Enter fullscreen mode Exit fullscreen mode
  • Avoid negative conditionals.

⛔️

function isRestaurantNotOpen(restaurant) {
  // ...
}

if(!isRestaurantNotOpen(restaurant)) {
  // ...
}
Enter fullscreen mode Exit fullscreen mode


function isRestaurantOpen(restaurant) {
  // ...
}

if(isRestaurantOpen(restaurant)) {
  // ...
}
Enter fullscreen mode Exit fullscreen mode
  • Avoid conditional whenever possible. Although this sounds very difficult, you should prefer polymorphism and inheritance over conditional.

⛔️

class Restaurant {
  // ...
  getStandardOperationTime() {
    switch (this.type) {
      case 'Cafe':
        return this.getStandardOperationTime('Cafe');
      case 'FastFood':
        return this.getStandardOperationTime('FastFood');
      case 'Bar':
        return this.getStandardOperationTime('Bar');
    }
  }
}
Enter fullscreen mode Exit fullscreen mode


class Restaurant {
  // ...
}

class Cafe extends Restaurant {
  // ...
  getStandardOperationTime() {
    return this.standardOperationTime;
  }
}

class FastFood extends Restaurant {
  // ...
  getStandardOperationTime() {
    return this.standardOperationTime;
  }
}

class Bar extends Restaurant {
  // ...
  getStandardOperationTime() {
    return this.standardOperationTime;
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Classes

  • Prefer ES6 classes over ES5 plain function.

⛔️

const Restaurant = function(name) {
  if (!(this instanceof Restaurant)) {
    throw new Error("Instantiate Restaurant with `new` keyword");
  }
  this.name = name;
};

Restaurant.prototype.getSize = function getOperationTime() {
  // ...
};

const Cafe = function(name, location) {
  if (!(this instanceof Cafe)) {
    throw new Error("Instantiate Cafe with `new` keyword");
  }
  Restaurant.call(this, name);
  this.location = location;
};

Cafe.prototype = Object.create(Restaurant.prototype);
Cafe.prototype.constructor = Cafe;
Cafe.prototype.popularDishes = function popularDishes() { 
  // ...
};
Enter fullscreen mode Exit fullscreen mode


class Restaurant {

  constructor(name) {
    this.name = name;
  }

  getOperationTime() {
    // ...
  }
}

class Cafe extends Restaurant {

  constructor(name, location) {
    super(name);
    this.location = location;
  }

  getPopularDishes() {
    // ...
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Use method chaining.

⛔️

class Restaurant {

  constructor(name) {
    this.name = name;
  }

  setLocation(location) {
    this.location = location;
  }

  setCategory(category) {
    this.category = category;
  }

  save() {
    console.log(this.name, this.location, this.category);
  }
}

const restaurant = new Restaurant('FastFood');

product.setName('Fast Fried Chicken');
product.setLocation('Bogor');
product.save();
Enter fullscreen mode Exit fullscreen mode


class Restaurant {

  constructor(name) {
    this.name = name;
  }

  setName(name) {
    this.name = name;
    // Return this for chaining
    return this;
  }

  setLocation(location) {
    this.location = location;
    // Return this for chaining
    return this;
  }

  save() {
    console.log(this.name, this.location, this.category);
    // Return this for chaining
    return this;
  }
}

const restaurant = new Restaurant('Cafe')
    .setName('Kopi Kopian')
    .setLocation('Bandung')
    .save();
Enter fullscreen mode Exit fullscreen mode
  • You should prefer composition over inheritance whenever you can. Quoting from clean-code-javascript by Ryan McDermott, here is a decent list of when inheritance makes more sense than composition:
  • Your inheritance represents an "is-a" relationship and not a "has-a" relationship (Human->Animal vs. User->UserDetails).
  • You can reuse code from the base classes (Humans can move like all animals).
  • You want to make global changes to derived classes by changing a base class. (Change the caloric expenditure of all animals when they move).

5. Javascript Style Guide

There are several principles or guides on how to write Javascript you and your team can follow.

6. Code Formatter and Linter

You can use a code formatter tool called Prettier to help you auto format your code based on your team's preference, which you can also integrate with linter, such as ESlint for bugs prevention.

Key Takeaways

Consistent on what you and your team has decided. And just like any other programming language, keep your code DRY (Don't Repeat Yourself) and KISS (Keep It Simple Stupid).

Reference:


Thanks for reading!
If you want to know more on CSS clean code, you can head over to this article

Would really appreciate if you could share your thoughts and feedback in the comment ✨

Top comments (0)