Objects and Data Structures

Use getters and setters

Using getters and setters to access data on objects could be better than simply
looking for a property on an object. “Why?” you might ask. Well, here’s an
unorganized list of reasons why:

  • When you want to do more beyond getting an object property, you don’t have
    to look up and change every accessor in your codebase.
  • Makes adding validation simple when doing a set.
  • Encapsulates the internal representation.
  • Easy to add logging and error handling when getting and setting.
  • You can lazy load your object’s properties, let’s say getting it from a
    server.

Bad:

  1. function makeBankAccount() {
  2. // ...
  3. return {
  4. balance: 0,
  5. // ...
  6. };
  7. }
  8. const account = makeBankAccount();
  9. account.balance = 100;

Good:

  1. function makeBankAccount() {
  2. // this one is private
  3. let balance = 0;
  4. // a "getter", made public via the returned object below
  5. function getBalance() {
  6. return balance;
  7. }
  8. // a "setter", made public via the returned object below
  9. function setBalance(amount) {
  10. // ... validate before updating the balance
  11. balance = amount;
  12. }
  13. return {
  14. // ...
  15. getBalance,
  16. setBalance,
  17. };
  18. }
  19. const account = makeBankAccount();
  20. account.setBalance(100);

Make objects have private members

This can be accomplished through closures (for ES5 and below).

Bad:

  1. const Employee = function(name) {
  2. this.name = name;
  3. };
  4. Employee.prototype.getName = function getName() {
  5. return this.name;
  6. };
  7. const employee = new Employee('John Doe');
  8. console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe
  9. delete employee.name;
  10. console.log(`Employee name: ${employee.getName()}`); // Employee name: undefined

Good:

  1. function makeEmployee(name) {
  2. return {
  3. getName() {
  4. return name;
  5. },
  6. };
  7. }
  8. const employee = makeEmployee('John Doe');
  9. console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe
  10. delete employee.name;
  11. console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe