Open
Description
工厂模式
function createPerson(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.say = function () {
console.log(this.name + this.age + this.job);
}
return o;
}
缺点: 没有解决对象识别问题,即无法判断对象的类型
通过constructor属性和instanceof操作符无法正确获得工厂模式创建的对象类型,她们返回的都是基类Object类型
var person = createPerson("Tom", 26, "SoftWare");
console.log(person instanceof createPerson); // false
console.log(person.constructor == createPerson); // false
console.log(person instanceof Object); // true
console.log(person.constructor == Object); // true
构造函数模式
构造函数在不返回值的情况下,默认会返回新对象实例,构造函数解决了对象类型检测问题
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.say = function () {
console.log(this.name + this.age + this.job);
}
}
var person = new Person("Jerry", 18, "Student");
console.log(person instanceof Person); // true
console.log(person.constructor == Person); // true
寄生构造函数模式
工厂模式 + return + new实例化
function ParasiticPerson(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.say = function () {
console.log(this.name + this.age + this.job);
}
return o;
}
为什么要用这种模式呢?
如果在其他模式(工厂模式、构造函数模式、原型模式等)都不适合的情况下采用寄生构造函数模式,采用这种模式的一个优势在于它可以返回重写后的对象实例(比如说定制某个方法),而不是返回构造函数默认的对象实例。
与工厂模式比较,区别
- 寄生构造函数模式用new创建新对象实例;
var person = new ParasiticPerson("Nicholas", 29, "SoftWare Engineer");
console.log(person instanceof ParasiticPerson); // false
console.log(person.constructor == ParasiticPerson); // false
console.log(person instanceof Object); // true
console.log(person.constructor == Object); // true
但是,与工厂模式相同的是,寄生构造函数模式的实例也不能正确检测其类型
稳妥构造函数模式
与寄生构造函数模式有些类型,但不同点有二:
- 构造函数内部不使用
this
; - 创建对象实例不使用
new
使用稳妥构造函数模式的优点是安全性。
function DurablePerson(name, age, job) {
var o = new Object();
o.say = function () {
console.log(name + age + job); // 注意:不使用this,而使用参数传入的变量
}
return o;
}
这种模式创建的实例也不能正确检测其类型
var person = DurablePerson("james", 29, "Ball Star");
console.log(person instanceof DurablePerson); // false
console.log(person.constructor == DurablePerson); // false
console.log(person instanceof Object); // true
console.log(person.constructor == Object); // true
总结
工厂模式、寄生构造函数模式、稳妥构造函数模式创建的实例都不能检测其类型,共同的原因是它们都在构造函数内部返回了另一个对象(末尾都有return语句),而不再是构造函数默认的对象(构造函数在不返回值的情况下,默认会返回新对象实例)。
这时候返回的对象与构造函数或构造函数的原型之间没有关系,这就是不能正确检测其实例对象类型的根本原因。