你明白寄生构造函数模式了吗
前言
在《JavaScript高级程序设计》面向对象的程序设计中,在关于如何创建对象时,有个章节是介绍寄生构造函数模式,这个模式虽然并不是很常用,但我在第一次在书中读到这部分时,并不是很明白书中提到的 ”Person函数创建了一个新对象,并以相应的属性和方法初始化该对象,然后又返回了这个对象。除了使用new操作符并把使用的包装函数叫做构造函数之外,这个模式跟工厂模式其实是一模一样的。构造函数在不返回值的情况下,默认会返回新对象实例。而通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值。“ 以及 ”有一点需要说明:首先,返回的对象与构造函数或者与构造函数的原型属性之间没有关系;也就是说,构造函数返回的对象与在构造函数外部创建的对象没有什么不同。为此,不能依赖instanceof操作符来确定对象类型。由于存在上述问题,我们建议在可以使用其他模式的情况下,不要使用这种模式。“
当时对这两段话很是困惑,如今再读这本书,突然发现对这两段话已经可以理解了,那么接下来就来说一下我的理解吧。
正文
先附上书中提到的例子:
function Person (name,age,job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var friend1 = new Person('lisi',29,'Software Engineer');
我们再附上工厂模式:
function person (name,age,job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var friend2 = person('lisi',29,'Software Engineer')
这里可以比较明显的看出寄生构造函数模式与工厂模式的区别,即寄生构造函数模式使用了new去实例化一个对象即 new Person(),而工厂模式是直接调用函数person(),这两者创建的实例其实都是一个Object的实例,用console.dir(friend1)和console.dir(friend2),
然后是friend2
可以发现friend1和friend2是一样的,那么如果寄生构造函数模式在去掉return之后再去用new实例化对象呢:
function Person (name,age,job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
}
var friend1 = new Person('lisi',29,'Software Engineer');
再次用console.dir(friend1)控制台打印friend1:
可以看出这次的friend1就已经是一个Person的实例了,这也就是说在寄生构造函数模式使用return后,会切断实例化对象与构造函数Person的联系。
现在我的只是还不够不能解释为什么在return返回内部实例化的对象后,在使用new操作符就修改了实例化的对象的原型,后面如果我弄懂了会继续补充。