前提已经提到,JavaScript 没有接口,因此抽象依赖于隐性契约。也就是说,一个对象/类会把方法和属性暴露给另一个对象/类。在下面的例子中,隐性契约是任何用于 InventoryTracker 的 Request 模块都应该拥有 requestItems 方法。
不好:
class InventoryTracker { constructor(items) { this.items = items; // 不好:我们创建了一个依赖于特定请求的实现。 // 我们应该只依赖请求方法:`request` 的 requestItems this.requester = new InventoryRequester(); } requestItems() { this.items.forEach((item) => { this.requester.requestItem(item); }); } } class InventoryRequester { constructor() { this.REQ_METHODS = ['HTTP']; } requestItem(item) { // ... } } let inventoryTracker = new InventoryTracker(['apples', 'bananas']); inventoryTracker.requestItems();
好:
class InventoryTracker { constructor(items, requester) { this.items = items; this.requester = requester; } requestItems() { this.items.forEach((item) => { this.requester.requestItem(item); }); } } class InventoryRequesterV1 { constructor() { this.REQ_METHODS = ['HTTP']; } requestItem(item) { // ... } } class InventoryRequesterV2 { constructor() { this.REQ_METHODS = ['WS']; } requestItem(item) { // ... } } // 通过构建外部依赖并注入它们,我们很容易把请求模块替换成 // 一个使用 WebSocket 的新模块。 let inventoryTracker = new InventoryTracker(['apples', 'bananas'], new InventoryRequesterV2()); inventoryTracker.requestItems();
多用 ES6 类语法,少用 ES5 构造函数语法
在经典的 ES5 的类定义中,很难找到易读的继承、构造、方法定义等。如果你需要继承(你会发现做不到),那就应该使用类语法。不过,应该尽可能使用小函数而不是类,直到你需要更大更复杂的对象。
不好:
var Animal = function(age) { if (!(this instanceof Animal)) { throw new Error("Instantiate Animal with `new`"); } this.age = age; }; Animal.prototype.move = function() {}; var Mammal = function(age, furColor) { if (!(this instanceof Mammal)) { throw new Error("Instantiate Mammal with `new`"); } Animal.call(this, age); this.furColor = furColor; }; Mammal.prototype = Object.create(Animal.prototype); Mammal.prototype.constructor = Mammal; Mammal.prototype.liveBirth = function() {}; var Human = function(age, furColor, languageSpoken) { if (!(this instanceof Human)) { throw new Error("Instantiate Human with `new`"); } Mammal.call(this, age, furColor); this.languageSpoken = languageSpoken; }; Human.prototype = Object.create(Mammal.prototype); Human.prototype.constructor = Human; Human.prototype.speak = function() {};
好:
class Animal { constructor(age) { this.age = age; } move() {} } class Mammal extends Animal { constructor(age, furColor) { super(age); this.furColor = furColor; } liveBirth() {} } class Human extends Mammal { constructor(age, furColor, languageSpoken) { super(age, furColor); this.languageSpoken = languageSpoken; } speak() {} }
内容版权声明:除非注明,否则皆为本站原创文章。