对象和数据结构

使用 getters 和 setters

JS 没有接口或类型,因此实现这一模式是很困难的,因为我们并没有类似 publicprivate 的关键词。

然而,使用 getters 和 setters 获取对象的数据远比直接使用点操作符具有优势。为什么呢?

  1. 当需要对获取的对象属性执行额外操作时。
  2. 执行 set 时可以增加规则对要变量的合法性进行判断。
  3. 封装了内部逻辑。
  4. 在存取时可以方便的增加日志和错误处理。
  5. 继承该类时可以重载默认行为。
  6. 从服务器获取数据时可以进行懒加载。

反例:

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

正例:

  1. class BankAccount {
  2. constructor() {
  3. this.balance = 1000;
  4. }
  5. // It doesn't have to be prefixed with `get` or `set` to be a getter/setter
  6. withdraw(amount) {
  7. if (verifyAmountCanBeDeducted(amount)) {
  8. this.balance -= amount;
  9. }
  10. }
  11. }
  12. let bankAccount = new BankAccount();
  13. // Buy shoes...
  14. bankAccount.withdraw(100);

让对象拥有私有成员

可以通过闭包完成

反例:

  1. var Employee = function(name) {
  2. this.name = name;
  3. }
  4. Employee.prototype.getName = function() {
  5. return this.name;
  6. }
  7. var 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. var Employee = (function() {
  2. function Employee(name) {
  3. this.getName = function() {
  4. return name;
  5. };
  6. }
  7. return Employee;
  8. }());
  9. var employee = new Employee('John Doe');
  10. console.log('Employee name: ' + employee.getName()); // Employee name: John Doe
  11. delete employee.name;
  12. console.log('Employee name: ' + employee.getName()); // Employee name: John Doe