什么时候使用模块vs原型?

use*_*655 4 javascript design-patterns

模块模式与原型模式似乎在js中做类似的事情.它们基本上包装了一堆js代码来封装并提供一种OO接口.这些技术本质上是可以互换的,还是应该使用其中一种技术而不是另一种?

Nav*_*dar 12

模块模式

模块模式的典型用法是用于命名空间.如果您有单个实例存储相关的函数和对象.

在这里看一个例子

我们将Customer和VipCustomer类包装在一个公共名称空间中.

var Fenton = (function () {
    function Customer(name) {
        this.name = name;
    }
    Customer.prototype = {
        constructor: Customer,
        greet: function () {
            return this.name + ' says hi!';
        }
    };
    function VipCustomer(name, discountPercentage) {
        Customer.call(this, name);
        this.discountPercentage = discountPercentage;
    }
    VipCustomer.prototype = new Customer();
    VipCustomer.prototype.constructor = VipCustomer;

    return {
        Customer: Customer,
        VipCustomer: VipCustomer
    };
}());
var steve = new Fenton.Customer('Steve');
var todd = new Fenton.VipCustomer('Todd', 10);
Run Code Online (Sandbox Code Playgroud)

所以我们可以在模块中添加构造函数并像这样调用:

new MyNamespace.MyModule.MyClass(arguments)
Run Code Online (Sandbox Code Playgroud)

原型模式

另一方面,原型模式是通过克隆基于现有对象的模板创建对象的模式.

我们可以将原型模式视为基于原型继承,我们创建的对象充当其他对象的原型.原型对象本身有效地用作构造函数创建的每个对象的蓝图.如果使用的构造函数的原型包含一个名为name的属性(根据下面的代码示例),那么由同一个构造函数创建的每个对象也将具有相同的属性.

在现有(非JavaScript)文献中查看此模式的定义,我们可能会再次找到对类的引用.现实情况是原型继承避免完全使用类.理论上没有"定义"对象也没有核心对象.我们只是创建现有功能对象的副本.

  • 使用原型模式的好处之一是我们正在使用JavaScript本身提供的原型优势,而不是试图模仿其他语言的功能.对于其他设计模式,情况并非总是如此.
  • 这种模式的另一个优点是它很容易实现继承,并且可以很好地提高性能.

正如ECMAScript 5标准中所定义的那样,需要使用Object.create(我们之前在本节前面已经讨论过).Object.create创建一个具有指定原型的对象,并且还可以选择包含指定的属性

例如Object.create( prototype, optionalDescriptorObjects ).

这里的例子 -

var myCar = {

  name: "Ford Escort",

  drive: function () {
    console.log( "Weeee. I'm driving!" );
  },

  panic: function () {
    console.log( "Wait. How do you stop this thing?" );
  }

};

// Use Object.create to instantiate a new car
var yourCar = Object.create( myCar );

// Now we can see that one is a prototype of the other
console.log( yourCar.name );
Run Code Online (Sandbox Code Playgroud)

如果你想创建原型模式,Object.create那么就可以这样做

var vehiclePrototype = {

  init: function ( carModel ) {
    this.model = carModel;
  },

  getModel: function () {
    console.log( "The model of this vehicle is.." + this.model);
  }
};


function vehicle( model ) {

  function F() {};
  F.prototype = vehiclePrototype;

  var f = new F();

  f.init( model );
  return f;

}

var car = vehicle( "Ford Escort" );
car.getModel();
Run Code Online (Sandbox Code Playgroud)

从这里阅读更多设计模式:

https://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript

https://addyosmani.com/resources/essentialjsdesignpatterns/book/#prototypepatternjavascript