一、构造器模式
通俗讲构造器就是创建一个对象实例时所用到的函数。通过new Constructor(),返回该实例。
在js中想要创建一个对象可以通过以下三种方式:
var obj1 = {};
// or
var obj2 = Object.create(null);
// or
var obj3 = new Object();
对于最后一种其实使用到的就是构造器,只不过这个构造器比较特殊是Object。
创建一个自己的构造器:
function Student(name, age){
this.name = name;
this.age = age;
this.getName = function(){ return this.name};
}
//创建一个实例
var student = new Student("alex", 24);
student.getName(); // "alex"
上面构造函数有一个缺点,就是每次声明一个新实例,getName引用的函数都要重新创建一遍,如果我们希望所有的实例都引用同一个getName方法,可以使用原型,如下:
function Student(name, age){
this.name = name;
this.age = age;
// this.getName = function(){ return this.name};
}
Student.prototype.getName = function(){ return this.name};
//创建一个实例
var student1 = new Student("alex", 24);
var student2 = new Student("John", 24);
if(student1.getName == student2.getName){
console.log("两个实例引用同一个函数")
} // "两个实例引用同一个函数"
Question:在new一个对象的过程中都发生了哪些事情?
答:
- 创建一个新对象,比如:var obj = {};
- 将新对象的_proto_属性指向构造函数的原型对象;
- 将构造函数的作用域指向新对象,即将this指向obj;
- 执行构造函数内部的代码,将属性添加给this对象;
- 返回新对象obj;
二、工厂模式
工厂模式的作用也是为了创建对象实例,它没有明确要求创建哪个实例,而是提供一个公共的接口,我们可以在其中指定我们要创建什么对象,举个例子:
// 定义一个生产car的Car构造器
function Car( options ) {
// some defaults
this.doors = options.doors || 4;
this.state = options.state || "brand new";
this.color = options.color || "silver";
}
// 定义一个生产卡车的Truck构造器
function Truck( options){
this.state = options.state || "used";
this.wheelSize = options.wheelSize || "large";
this.color = options.color || "blue";
}
// FactoryExample.js
// 定义一个生产汽车的工厂(其实就是一个对象)
function VehicleFactory() {}
// Define the prototypes and utilities for this factory
// 将默认生产的车型设为Car
VehicleFactory.prototype.vehicleClass = Car;
//工厂方法
VehicleFactory.prototype.createVehicle = function ( options ) {
if( options.vehicleType === "car" ){
this.vehicleClass = Car;
}else{
this.vehicleClass = Truck;
}
return new this.vehicleClass( options );
};
// 通过传入一个对象,来生产我们想要的实例(车型)
var carFactory = new VehicleFactory();
var car = carFactory.createVehicle( {
vehicleType: "car",
color: "yellow",
doors: 6 } );
// Outputs: true
console.log( car instanceof Car );
// Outputs: Car object of color "yellow", doors: 6 in a "brand new" state
console.log( car );
下面是一个更具实用意义的抽象工厂模式
var AbstractFactory = (function(){
var types = {Car:Car, Truck:Truck};
return {
// type代表生产汽车的类型,customizations是创建汽车实例所需要的参数。
getVehicle: function(type, customizations){
var Vehicle = types[type];
return (Vehicle ? new Vehicle(customizations) : null);
},
// type代表所要生产的汽车类型, Vehicle代表该汽车类型的构造函数
registerVehicle: function( type, Vehicle ){
var proto = Vehicle.prototype;
// 构造函数必须满足一些要求,比如要有drive、brakDown方法,才可以注册到工厂仓库中。
if ( proto.drive && proto.breakDown ) {
types[type] = Vehicle;
}
return AbstractVehicleFactory;
}
}
})()