JavaScript Best Practices — Classes and Modules

John Au-Yeung - Jul 18 '20 - - Dev Community

JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.

In this article, we’ll look at what should be in our class methods, and also the best ways to use modules.

Class Methods Should Either Reference this Or Be Made Into a Static Method

A JavaScript class can have static or instance methods. If it’s an instance method , then it should reference this . Otherwise, it should be a static method.

For instance, we should write a class that’s like the following code:

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

  static greet() {
    return 'hi'
  }

  greetWithName() {
    return `hi ${this.name}`;
  }
}

In the code above, we have the static greet method which doesn’t reference this and the greetWithName method, which references this.name .

Static methods are shared with all instances of the class and instance methods are part of the instance, so it makes sense it references this .

Use ES6 Modules Import and Export Over Non-Standard Module Systems

With ES6, modules are a standard feature of JavaScript. We can divide our code into modules and only export code that we want to expose to the outside.

Also, we can selectively import members from another module.

Before ES6, there’re various module systems like RequireJS and CommonJS. They’re similar to what ES6 modules do today. However, ES6 modules can do what they do and they’re a JavaScript standard.

Therefore, we should just use ES6 modules over other kinds of modules so that we won’t have to worry about those kinds of modules going away or compatibility issues with other kinds of module systems.

For instance, instead of writing the following code to export and import modules:

module.js

module.exports = {
  foo: 1
};

index.js

const { foo } = require("./module");
console.log(foo);

We write:

module.js

export const foo = 1;

index.js

import { foo } from "./module";
console.log(foo);

In the first example, we used module.exports to export a member as a property of an object.

Then we imported the foo property with the require function. This is the old way with CommonJS module which is used before JavaScript has modules as a standard feature.

The second example does the same thing using standard JavaScript modules. We export the member foo in module.js and then import foo inindex.js .

JavaScript modules have been a standard for a long time and it’s supported in both browsers and Node.js natively since version 12, we can use regular JavaScript modules anywhere.

If not, we can use transpilers like Browserify, Webpack, or Parcel to transform module code into ES5 code.

Do Not Use Wildcard Imports

Wildcard imports import everything. It’s denoted by an asterisk symbol.

For instance, we do a wildcard import by writing the following code:

module.js

export const foo = 1;

index.js

import * as module from "./module";
console.log(module.foo);

In the code above, we imported the whole module.js module by using the * and the as keyword to name the module that we imported so that we can reference it in the line below.

This isn’t good because we usually don’t need all the members of a module, so it’s not efficient to import everything.

Instead, we should import only the members that we need. We should write:

import { foo } from "./module";
console.log(foo);

to import just the foo member which we need.

Photo by chuttersnap on Unsplash

Do Not Export Directly From an Import

We shouldn’t export directly from an import. This means that we shouldn’t use the as keyword to rename the export directly within the export to something else.

It’s clearer to separate them from their own line. For instance, we can write the following code to do that:

module.js

export const foo = 1;

bar.js

export { foo as bar } from "./module";

index.js

import { bar } from "./bar";
console.log(bar);

In the code above, we exported the foo member from module.js as bar by using the export statement.

We shouldn’t do that since it’s not clear that we’re both importing from module.js and exporting the member as bar at the same time.

Instead, we should write the following in bar.js :

import { foo } from "./module";
export { foo as bar } from "./module";

This way, it’s clear that we’re both importing and exporting in one module.

Conclusion

Class methods should reference this if it’s an instance method or be static if they don’t.

We should use ES6 modules since it’s a JavaScript standard. Also, we should separate imports and exports and shouldn’t import everything from a module.

The post JavaScript Best Practices — Classes and Modules appeared first on The Web Dev.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .