1.工厂模式
定义:工厂模式是一种众所周知的设计模式,广泛应用于软件工程领域,用于抽象创建特定对象的过程。工厂模式是一种创建型模式,简单来说,工厂模式就是创建对象的一种方式。
作用:创建对象,降低代码冗余度
首先我们用字面量或者使用new来创建的形式来创建对象,然后再用工厂模式,将他们对比一下
var person = {
name: "zhangsan",
age: 18,
sayName: function(){
console.log(this.name);
}
}
//字面量形式
var person = new Object();
//为这个实例化的对象添加属性
person.name = "zhangsan";
person.age = 18;
person.sayName = function() {
console.log(this.name)
}
//new Object形式创建
//将创建对象的代码封装在一个函数中
function createPerson(name, age) {
var person = new Object();
person.name = name;
person.age = age;
person.sayName = function () {
console.log(this.name);
}
return person;
}
//利用工厂函数来创建对象
var person1 = createPerson("zhangsan", 18,);
var person2 = createPerson("lisi", 20,);
//工厂模式创建
明显看出,我们使用工厂模式来创建对象之后,可以通过封装函数的形式,每当要新增一个人的信息时可以直接调用该函数来创建对象。但是工厂模式也有缺点:
这种方式本质上是将创建对象的过程进行了封装,本质并没有改变,我们创建一个student时无法知道其具体的数据类型,只知道这是一个对象,往往实际开发中我们需要确定这个对象到底是个Person的实例还是Dog的实例。所以下面我们将使用自定义构造函数。
2.构造函数模式
1.自定义构造函数
function Person(name, age) {
this.name = name;
this.age = age;
this.sayName = function () {
console.log(this.name);
}
}
var person1 = new Person('zhangsan', 29);
var person2 = new Person('lisi', 19;)
person1.sayName(); // zhangsan
person2.sayName(); // lisi
这里的Person()构造函数代替了工厂模式的createPerson,区别在于自定义构造函数没有显示创建对象,属性值和方法直接赋值给了this,没有return
构造函数同样也有它的问题:其定义的方法会在每个实例上都创建一遍
3.原型模式
每个函数都会创建一个prototype属性,这个属性是一个对象,这个对象是通过调用构造函数创建的对象的原型,使用原型对象的好处:在它上面定义的属性和方法可以被对象实例共享
function Person(){}
Person.prototype.name = "zhangsan";
Person.prototype.age = 18;
Person.prototype.sayName = function () {
console.log(this.name);
};
var person1 = new Person();
person1.sayName(); // zhangsan
var person2 = new Person();
person2.sayName(); // zhangsan
console.log(person1.sayName == person2.sayName); // true
这里person1和person2都访问相同的属性和相同的sayName函数
原型模式也同样有它的问题:它弱化了向构造函数传递初始化参数的能力,会导致所有实例默认都取得相同的属性值,原型的主要问题源于它的共享性
4.组合模式(目前用得较多)
组合模式结合了构造函数模式和原型模式,构造函数用于定义实例属性,原型模式用于定义方法和共享属性
function Person(name, age) {
this.name = name;
this.age = age;
this.firends = ['zhangsan', 'lisi'];
}
Person.prototype = {
constructor: Person,
sayName: function () {
console.log(this.name);
}
};
var p1 = new Person('larry', 44);
var p2 = new Person('terry', 39);
p1.firends.push('robin');
console.log(p1.firends); // [ 'zhangsan', 'lisi', 'robin' ]
console.log(p2.firends); // [ 'zhangsan', 'lisi' ]
console.log(p1.firends === p2.firends); // false p1有新增朋友
console.log(p1.sayName === p2.sayName); // true 访问的是同一个sayName函数