浅谈JavaScript 代码整洁之道(8)

好:

function newRequestModule(url) {
 // ...
}

var req = newRequestModule;
inventoryTracker('apples', req, 'www.inventory-awesome.io');

对象和数据结构

使用 getter 和 setter

JavaScript 没有接口或者类型,也没有像 public 和 private 这样的关键字,所以很难应用设计模式。实事上,在对象上使用 getter 和 setter 访问数据远好于直接查找对象属性。“为什么?”你可能会这样问。那好,下面列出了原因:

  1. 你想在获取对象属性的时候做更多的事,不必在代码中寻找所有访问的代码来逐个修改。
  2. 在进行 set 的时候可以进行额外的数据检验。
  3. 封装内部表现。
  4. 在获取或设置的时候易于添加日志和错误处理。
  5. 继承当前类,可以重写默认功能。
  6. 可以对对象属性进行懒加载,比如说从服务器获取属性的数据。

不好:

class BankAccount {
 constructor() {
    this.balance = 1000;
 }
}

let bankAccount = new BankAccount();

// 买鞋...
bankAccount.balance = bankAccount.balance - 100;

好:

class BankAccount {
 constructor() {
    this.balance = 1000;
 }

 // It doesn't have to be prefixed with `get` or `set` to be a getter/setter
 withdraw(amount) {
  if (verifyAmountCanBeDeducted(amount)) {
   this.balance -= amount;
  }
 }
}

let bankAccount = new BankAccount();

// 买鞋...
bankAccount.withdraw(100);

让对象拥有私有成员

这可以通过闭包实现(ES5以之前的版本)。

不好:

var Employee = function(name) {
 this.name = name;
}

Employee.prototype.getName = function() {
 return this.name;
}

var employee = new Employee('John Doe');
console.log('Employee name: ' + employee.getName()); // Employee name: John Doe
delete employee.name;
console.log('Employee name: ' + employee.getName()); // Employee name: undefined

好:

var Employee = (function() {
 function Employee(name) {
  this.getName = function() {
   return name;
  };
 }

 return Employee;
}());

var employee = new Employee('John Doe');
console.log('Employee name: ' + employee.getName()); // Employee name: John Doe
delete employee.name;
console.log('Employee name: ' + employee.getName()); // Employee name: John Doe


单一职责原则 (SRP)

正如《代码整洁之道》所说,“不应该有超过一个原因来改变类”。往一个类里塞进许多功能是件诱人的事情,就像在坐飞机的时候只带一个手提箱一样。这带来的问题是,你的类不会在概念上有凝聚力,会有很多因素造成对它的改变。让你的类需要改变的次数最少是件非常重要的事情。这是因为如果一个类里塞入了太多功能,你只修改它的一部分,可能会让人难以理解它为何会影响代码库中其它相关模块。