原型模式

原型模式侧重于创建一个对象,该对象可以通过原型继承用作其他对象的蓝图。由于 JS 中对原型继承的原生支持,这种模式本身很容易在 JavaScript 中使用,这意味着我们不需要花时间或精力模仿这种拓扑。

在原型上创建方法

function Welcome(name) {
  this.name = name;
}
Welcome.prototype.sayHello = function() {
  return 'Hello, ' + this.name + '!';
}

var welcome = new Welcome('John');

welcome.sayHello();
// => Hello, John!

原型继承

通过以下模式从父对象继承相对容易

ChildObject.prototype = Object.create(ParentObject.prototype);
ChildObject.prototype.constructor = ChildObject;

其中 ParentObject 是你希望继承原型函数的对象,而 ChildObject 是你希望将它们放在上面的新对象。

如果父对象具有在其构造函数中初始化的值,则在初始化子对象时需要调用父构造函数。

你可以在 ChildObject 构造函数中使用以下模式执行此操作。

function ChildObject(value) {
    ParentObject.call(this, value);
}

完成上述操作的完整示例

function RoomService(name, order) {
  // this.name will be set and made available on the scope of this function
  Welcome.call(this, name);
  this.order = order;
}

// Inherit 'sayHello()' methods from 'Welcome' prototype
RoomService.prototype = Object.create(Welcome.prototype);

// By default prototype object has 'constructor' property. 
// But as we created new object without this property  -  we have to set it manually,
// otherwise 'constructor' property will point to 'Welcome' class
RoomService.prototype.constructor = RoomService;

RoomService.prototype.announceDelivery = function() {
  return 'Your ' + this.order + ' has arrived!';
}
RoomService.prototype.deliverOrder = function() {
  return this.sayHello() + ' ' + this.announceDelivery();
}

var delivery = new RoomService('John', 'pizza');

delivery.sayHello();
// => Hello, John!,

delivery.announceDelivery();
// Your pizza has arrived!

delivery.deliverOrder();
// => Hello, John! Your pizza has arrived!