javascript - 何时使用模块与原型(prototype)?

标签 javascript design-patterns

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

最佳答案

模块模式
模块模式的典型用法是用于命名空间。如果有一个实例存储相关的函数和对象。
这里有一个例子
我们将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);

所以我们可以在模块中添加构造函数,然后像这样调用:
new MyNamespace.MyModule.MyClass(arguments)

原型模式
另一方面,原型模式是通过克隆现有对象的模板来创建对象的模式。
我们可以认为原型模式是基于原型继承的,在这里我们创建的对象充当其他对象的原型。原型对象本身被有效地用作构造器创建的每个对象的蓝图。如果使用的构造函数的原型包含一个名为name的属性(如下面的代码示例所示),那么由同一个构造函数创建的每个对象也将具有相同的属性。
在现有的(非JavaScript)文献中回顾这种模式的定义,我们可能会再次发现对类的引用。事实上,原型继承避免了完全使用类。理论上既没有“定义”对象,也没有核心对象。我们只是在创建现有功能对象的副本。
使用原型模式的好处之一是
使用javascript必须提供的原型优势
不是试图模仿其他人的特征
语言。对于其他设计模式,情况并非总是如此。
这种模式的另一个优点是它易于实现
继承,以及它能很好地提高性能。
正如ecmascript 5标准中定义的那样,需要使用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 );

如果您希望创建不带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();

从这里阅读更多的设计模式:
https://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript
https://addyosmani.com/resources/essentialjsdesignpatterns/book/#prototypepatternjavascript

关于javascript - 何时使用模块与原型(prototype)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38641569/

相关文章:

javascript - Angular2 *ng用于推开元素的动画

javascript - 使用 ng-maxlength 时不会触发 $watch 监听器

javascript - 使用 jQuery 添加文本后,嵌套 div float 在包含 div 之外

javascript - 在 html5 Canvas 内绘制 .tmx 平铺 map

javascript - 如何通过javascript识别 Canvas 中的区域

.net - 如何将 'GUI' 层排除在 'Business Logic' 层之外?

javascript - 如果所有 Li 都被隐藏,则显示消息

java - 分离常用方法的最佳方法

java 带有装饰器模式的条件日志记录

c# - 如何在单个 webapi 请求中使用单个对象并在所有子进程中填充其属性?