对象和数据结构

使用 getters 和 setters

JavaScript 没有接口或类型, 所以坚持这个模式是非常困难的, 因为我们没有 publicprivate
关键字。 正因为如此, 使用 getters 和 setters 来访问对象上的数据比简单的在一个对象上查找属性
要好得多。 “为什么?” 你可能会问, 好吧, 原因请看下面的列表:

  • 当你想在获取一个对象属性的背后做更多的事情时, 你不需要在代码库中查找和修改每一处访问;
  • 使用 set 可以让添加验证变得容易;
  • 封装内部实现;
  • 使用 getting 和 setting 时, 容易添加日志和错误处理;
  • 继承这个类, 你可以重写默认功能;
  • 你可以延迟加载对象的属性, 比如说从服务器获取。

不好的:

  1. class BankAccount {
  2. constructor() {
  3. this.balance = 1000;
  4. }
  5. }
  6. const bankAccount = new BankAccount();
  7. // Buy shoes...
  8. bankAccount.balance -= 100;

好的:

  1. class BankAccount {
  2. constructor(balance = 1000) {
  3. this._balance = balance;
  4. }
  5. // It doesn't have to be prefixed with `get` or `set` to be a getter/setter
  6. set balance(amount) {
  7. if (verifyIfAmountCanBeSetted(amount)) {
  8. this._balance = amount;
  9. }
  10. }
  11. get balance() {
  12. return this._balance;
  13. }
  14. verifyIfAmountCanBeSetted(val) {
  15. // ...
  16. }
  17. }
  18. const bankAccount = new BankAccount();
  19. // Buy shoes...
  20. bankAccount.balance -= shoesPrice;
  21. // Get balance
  22. let balance = bankAccount.balance;

让对象拥有私有成员

这个可以通过闭包来实现(针对 ES5 或更低)。

不好的:

  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

好的:

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