A module does not create a type!

Modules are the primary means to employ "Separation of Concerns" design principle. They, however, do not create a (data) "type." In our earlier example, there is only ever one instance of Account. Therefore, you cannot create different types of accounts, each having its own "balance."

// script.js file
import * as Account from "./account.js";

console.log(Account.getBalance());

Account.deposit(100);
Account.withdraw(20);

console.log(Account.getBalance());

To use Account as a type, you need JavaScript classes:

// account.js file
const INTEREST_RATE = 0.2;

class Account {
  constructor(balance) {
    this.balance = balance;
  }

  deposit(amount) {
    this.balance += amount;
  }

  withdraw(amount) {
    this.balance -= amount;
  }
}

export { INTEREST_RATE as interest, Account };

We can now use Account as a type:

// script.js file
import { Account } from "./account.js";

const checking = new Account(100);
checking.deposit(20);

console.log(checking.balance);

This may seem contrary to our goal of hiding "balance" since JavaScript classes do not provide information hiding (at the time of writing), and the "balance" is not protected (hidden) now.

You need to appreciate the difference between modules and classes:

  • Use classes to create types.
  • Use modules to modularize your JavaScript program.

The module construct and the class construct have the same goal of creating encapsulations: group data and behavior in logical units. The module construct further allows information hiding by creating scope. At the time of writing, information hiding is not achieved by classes. On the other hand, classes create abstractions (types) which you can instantiate or extend.