在介绍寄生构造函数模式时,先来介绍一下工厂模式
1.工厂模式
工厂模式是软件工程领域中一种广为认知的设计模式,这种模式抽象了具体创建对象的过程,因为在ECMAScript中无法创建类。开发人员就发明了一种函数,用函数来封装以特定接口创建对象的细节。
function createPerson(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName= function(){
return (this.name)
};
return o;
}
var person1 = createPerson('ZhangSan', 29, 'Software Enginner ');
var person2 = createPerson('LiSi', 27, 'Doctor ');
使用工厂模式,可以无数次的调用这个函数。而每次它都会返回一个具有三个属性和一个方法的对象。工厂模式虽然解决了创建多个对象的问题,但却没有解决对象识别的问题(怎样知道一个对象的类型)
即
console.log(person1 instanceof Object); //true
console.log(person2 instanceof Object); //true
console.log(person1.constructor == Object); //true
console.log(person2.constructor == Object); //true
知道person1 和person2 都属于对象,却没办法知道对象的类型。所以就出现了构造函数。
而构造函数上节已经讲过,现在我们要看的就是和工厂模式的定义对象的方法非常相似的寄生构造函数模式。
2. 寄生构造函数模式
在我们前几次讲的几种模式都不适用的情况下,可以使用这种。
这种模式的基本思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码。然后再返回新创建的函数。
function Person(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName= function(){
return (this.name)
};
return o;
}
var person1 = new Person('ZhangSan', 29, 'Software Enginner ');
var person2 = new Person('LiSi', 27, 'Doctor ');
从表面上看这像是很典型的构造函数。但是除了使用new操作符并把使用的包装函数叫做构造函数之外,这个模式其实跟工厂模式是一模一样的。构造函数在不返回值的情况下,默认返回新对象实例。而在构造函数的尾部添加一个return 语句,意味着可以重写调用构造函数时的返回值。
这个模式可以在特殊情况下,用来为对象创建构造函数。
function createPerson(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName= function(){
return (this.name)
};
return o;
}
function specialPerson(){
var persons = new createPerson('LiSi', 27, 'Doctor');
persons.alertMsg = function(){
alert('new message!');
}
return persons;
}
var person1 = new specialPerson();
person1.alertMsg(); //new message
alert(person1.sayName()); //LiSi
在上面的例子中,我们首先创建了构造函数createPerson(),然后再使用寄生构造函数模式为该函数的内部对象又添加了新的方法。
使用var person1 = new specialPerson();创建一个新实例。相当于利用使用构造函数specialPerson创建的实例,也可以访问createPerson中的属性和方法。
注意:返回的对象与构造函数或者构造函数的原型属性之间没有任何关系。也就是说,通过构造函数返回的对象与在构造函数外部创建的对象没有什么不同。因此不能依赖instanceof操作符来确定对象类型。所以一般不建议使用这种模式。
3 .稳妥构造函数模式
所谓稳妥对象,就是没有公共属性,而且其方法也不引用this的对象。稳妥对象最适合在一些安全的环境中(这些环境中会禁止使用this和new)。或者在防止数据被其他应用程序改动时使用。
稳妥构造函数模式遵循与寄生构造函数类似的模式。但有区别:
①.新创建对象的实例方法不使用this;
②.不使用new操作符调用构造函数
则根据稳妥函数的要求,可以将前面的Person改写为:
function Person(name , age, job){
//创建要返回的对象
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(name);
}
//返回对象
return o;
}
var friend = Person("Nicholas", 29, "SoftWare Enginner");
friend.sayName(); //Nicholas
这样变量friend中保存的是一个稳妥对象,除了调用sayName之外,没有其他方法访问其数据成员。即使有其他代码会为这个对象添加新的方法或者数据成员,但也不会有别的方法访问到传入到构造函数中的原始数据。稳妥函数提供的这种安全性,使得它非常适合在某些安全执行环境下使用。